社区讨论

竞选本题最唐代码

P7230[COCI 2015/2016 #3] NEKAMELEONI参与者 2已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@mifkvgc6
此快照首次捕获于
2025/11/26 13:42
3 个月前
此快照最后确认于
2025/11/26 15:25
3 个月前
查看原帖
学生使用了一棵线段树一棵平衡树以及一个线段树分治。
CPP
#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){
    int s=0,w=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    return s*w;
}
inline void write(int x){
    if(x==0){putchar('0');return;}
    int len=0,k1=x,c[10005];
    if(k1<0)k1=-k1,putchar('-');
    while(k1)c[len++]=k1%10+'0',k1/=10;
    while(len--)putchar(c[len]);
}
mt19937 rnd(time(0));
const int N=1e5+5,M=5e6+5,INF=2e9+9;
int rt,top,n,m,q;array<int,4>st[M];int vifhq[N],g[N];
struct FHQ_Treap{
    struct Tr{int ls,rs,pri,key,siz;};vector<Tr>tr;int sz=0,rt=0;
    void push_up(int x){tr[x].siz=tr[tr[x].ls].siz+tr[tr[x].rs].siz+1;}
    void newnode(int x){tr.push_back({0,0,rnd(),x,1});sz++;}
    void split(int x,int y,int &L,int &R){
        if(x==0){L=R=0;return ;}
        if(tr[x].key<=y)L=x,split(tr[x].rs,y,tr[x].rs,R);
        else R=x,split(tr[x].ls,y,L,tr[x].ls);
        push_up(x);return ;
    }int merge(int L,int R){
        if(L==0||R==0)return L+R;
        if(tr[L].pri>tr[R].pri){
            tr[L].rs=merge(tr[L].rs, R);
            push_up(L);return L;
        }else{
            tr[R].ls=merge(L, tr[R].ls);
            push_up(R);return R;
        }
    }int insert(int x){
        int L,R;split(rt,x,L,R);
        newnode(x);rt=merge(merge(L, sz), R);
        return sz;
    }int del(int x){
        int L,M,R;
        split(rt,x,L,R);split(L,x-1,L,M);
        M=merge(tr[M].ls,tr[M].rs);
        rt=merge(merge(L,M),R);
        return rt;
    }int getrank(int x){
        int L,R,ans;
        split(rt,x-1,L,R);
        ans=tr[L].siz+1;rt=merge(L,R);
        return ans;
    }int kth(int x,int k){
        if(k==tr[tr[x].ls].siz+1)return x;
        if(k<=tr[tr[x].ls].siz)return kth(tr[x].ls,k);
        return kth(tr[x].rs,k-tr[tr[x].ls].siz-1);
    }int pre(int x){
        int L,R,ans;
        split(rt,x-1,L,R);
        if(L==0)ans=-INF;else ans=tr[kth(L,tr[L].siz)].key;
        rt=merge(L,R);
        return ans;
    }int suc(int x){
        int L,R,ans;
        split(rt,x,L,R);
        if(R==0)ans=INF;else ans=tr[kth(R,1)].key;
        rt=merge(L,R);
        return ans;
    }int count_val(int x){
        int L,R,M;
        split(rt,x-1,L,R); split(R,x,M,R);
        int ans=(M==0?0:tr[M].siz);
        R=merge(M,R);rt=merge(L,R);
        return ans;
    }int lower_bound(int x){
        int L,R,ans;
        split(rt,x-1,L,R);
        if(R==0) ans=INF;
        else ans=tr[kth(R,1)].key;
        rt=merge(L,R);
        return ans;
    }int prev_before_lb(int x){
        int L,R,ans;
        split(rt,x-1,L,R);
        if(L==0)ans=-INF;
        else ans=tr[kth(L,tr[L].siz)].key;
        rt=merge(L,R);
        return ans;
    }
}fhq[N];
int ans[N],a[N];vector<int>mp[N];
struct Sgt{
    struct Tr{int ls,rs,mx,mn,tag;}tr[N<<1];int cnt=0;
    #define ls(p) tr[p].ls
    #define rs(p) tr[p].rs
    void push_up(int p){
        // st.push({p,tr[p].mx,tr[p].mn,tr[p].tag});
        st[++top]={p,tr[p].mx,tr[p].mn,tr[p].tag};
        tr[p].mn=min(tr[ls(p)].mn,tr[rs(p)].mn);
        tr[p].mx=max(tr[ls(p)].mx,tr[rs(p)].mx);
    }void build(int &p,int pl,int pr){
        p=++cnt;if(pl==pr){tr[p].mx=-INF,tr[p].mn=INF;return ;}
        int mid=pl+pr>>1;
        build(ls(p),pl,mid);build(rs(p),mid+1,pr);push_up(p);
    }void add_tag(int p,int pl,int pr,int k){
        // st.push({p,tr[p].mx,tr[p].mn,tr[p].tag});
        st[++top]={p,tr[p].mx,tr[p].mn,tr[p].tag};
        tr[p].mx=tr[p].tag=k;tr[p].mn=k-pr+1;
    }void push_down(int p,int pl,int pr){
        if(tr[p].tag){
            int mid=pl+pr>>1;
            add_tag(ls(p),pl,mid,tr[p].tag);
            add_tag(rs(p),mid+1,pr,tr[p].tag);
            st[++top]={p,tr[p].mx,tr[p].mn,tr[p].tag};
        }tr[p].tag=0;
    }void upd(int p,int pl,int pr,int l,int r,int k){
        if(pl>=l&&pr<=r){add_tag(p,pl,pr,k);return ;}push_down(p,pl,pr);
        // cout<<l<<" "<<r<<" "<<k<<" "<<p<<" "<<pl<<" "<<pr<<endl;
        int mid=pl+pr>>1;
        if(l<=mid)upd(ls(p),pl,mid,l,r,k);
        if(mid<r)upd(rs(p),mid+1,pr,l,r,k);push_up(p);
    }
    int get(int p,int pl,int pr,int l,int r,int k){
        if(tr[p].mx<k)return INF;if(pl==pr)return pl;
        int mid=pl+pr>>1,ans=INF;push_down(p,pl,pr);
        if(l<=pl&&pr<=r){
            if(tr[ls(p)].mx>=k)return get(ls(p),pl,mid,l,r,k);
            else return get(rs(p),mid+1,pr,l,r,k);
        }if(l<=mid)ans=get(ls(p),pl,mid,l,r,k);
        if(r>mid&&ans==INF)ans=get(rs(p),mid+1,pr,l,r,k);
        return ans;
    }void update(int l,int r,int k){
        l=max(1ll,l),r=min(r,get(rt,1,n,1,n,k)-1);
        // cout<<l<<" "<<r<<endl;
        if(l>r)return ;upd(rt,1,n,l,r,k);
    }int getans(){return tr[1].mn;}
    #undef ls(p) tr[p].ls
    #undef rs(p) tr[p].rs
}SgT;
struct SGT{
    vector<pair<int,int>>tr[N<<2];
    int ls(int p){return p<<1;}
    int rs(int p){return p<<1|1;}
    void delet(int u,int k){
        while(top>k){
            auto [p,mx,mn,tag]=st[top--];
            SgT.tr[p].mx=mx,SgT.tr[p].mn=mn,SgT.tr[p].tag=tag;
        }for(auto [l,r]:tr[u])fhq[r].insert(l);
    }void upd(int p,int pl,int pr,int l,int r,int a,int b){
        if(l>r)return ;if(pl>=l&&pr<=r){tr[p].push_back({a,b});return ;}
        int mid=pl+pr>>1;
        if(l<=mid)upd(ls(p),pl,mid,l,r,a,b);
        if(mid<r)upd(rs(p),mid+1,pr,l,r,a,b);
    }void solve(int p,int pl,int pr){
        // cout<<p<<" "<<pl<<" "<<pr<<endl;
        int pre=top;
        for(auto [l,r]:tr[p]){
            fhq[r].del(l);
            if(fhq[r].count_val(l))continue;
            int it=fhq[r].lower_bound(l);
            int pv=fhq[r].prev_before_lb(l);
            SgT.update(pv+1,l,it);
        }if(pl==pr){ans[pl]=SgT.getans();delet(p,pre);return ;}
        int mid=pl+pr>>1;
        solve(ls(p),pl,mid);solve(rs(p),mid+1,pr);
        delet(p,pre);return ;
    }
}sgt;

signed main(){
    // freopen("x.in","r",stdin);
    // freopen("x.out","w",stdout);
    n=read(),m=read(),q=read();SgT.build(rt,1,n);
    for(int i=1;i<=m;i++){fhq[i].tr.push_back({0,0,0,0,0});fhq[i].insert(INF);fhq[i].insert(-INF);}
    for(int i=1;i<=n;i++){
        a[i]=read(); fhq[a[i]].insert(i);
        mp[i].push_back(a[i]);
    }for(int i=1;i<=q;i++){
        int op=read();
        if(op==1){
            int x=read(),y=read();
            fhq[y].insert(x);mp[x].push_back(y);
            sgt.upd(1,1,q,1,i-1,x,y);
            sgt.upd(1,1,q,i,q,x,a[x]);a[x]=y;
        }else vifhq[i]=1;
    }for(int i=1;i<=n;i++){
        if(i==1){for(int j=1;j<=m;j++)g[i]=max(g[i],fhq[j].lower_bound(i));continue;}
        g[i]=g[i-1];for(auto j:mp[i-1])g[i]=max(g[i],fhq[j].lower_bound(i));
    }for(int i=1;i<=n;i++)SgT.upd(rt,1,n,i,i,g[i]);
    sgt.solve(1,1,q);
    for(int i=1;i<=q;i++)if(ans[i]>INF/2)ans[i]=-1;
    for(int i=1;i<=q;i++)if(vifhq[i])cout<<ans[i]<<"\n";
    return 0;
}

回复

1 条回复,欢迎继续交流。

正在加载回复...