zoukankan      html  css  js  c++  java
  • 数据结构模板整理

    过滤一些较简单的如线段树、树状数组等,甚至树链剖分都被过滤了。

     左偏树https://www.luogu.org/problemnew/show/P3377

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e6+7;
    int n,Q,fa[N],lc[N],rc[N],w[N],d[N];
    int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
    int merge(int x,int y)
    {
        if(!x||!y)return x+y;
        if(w[x]>w[y]||w[x]==w[y]&&x>y)swap(x,y);
        rc[x]=merge(rc[x],y);
        if(d[lc[x]]<d[rc[x]])swap(lc[x],rc[x]);
        d[x]=d[rc[x]]+1;
        return x;
    }
    int main()
    {
        scanf("%d%d",&n,&Q);
        for(int i=1;i<=n;i++)scanf("%d",&w[i]),fa[i]=i;
        d[0]=-1;
        while(Q--)
        {
            int op,x,y;scanf("%d%d",&op,&x);
            if(op==1)
            {
                scanf("%d",&y);
                if(w[x]==-1||w[y]==-1)continue;
                int u=find(x),v=find(y);
                if(u!=v)fa[u]=fa[v]=merge(u,v);
            }
            else{
                if(w[x]==-1){puts("-1");continue;}
                y=find(x);
                printf("%d
    ",w[y]);
                w[y]=-1,fa[y]=merge(lc[y],rc[y]),fa[fa[y]]=fa[y];
            }
        }
    }

    主席树https://www.luogu.org/problemnew/show/P3834

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N=2e5+7;
    int n,Q,cnt,m,a[N],b[N],root[N],sum[N*30],lc[N*30],rc[N*30];
    int build(int l,int r)
    {
        int rt=++cnt,mid=(l+r)/2;
        sum[rt]=0;
        if(l<r)lc[rt]=build(l,mid),rc[rt]=build(mid+1,r);
        return rt;
    }
    int update(int prt,int l,int r,int k)
    {
        int rt=++cnt,mid=(l+r)/2;
        lc[rt]=lc[prt];rc[rt]=rc[prt];sum[rt]=sum[prt]+1;
        if(l==r)return rt;
        if(k<=mid)lc[rt]=update(lc[prt],l,mid,k);
        else rc[rt]=update(rc[prt],mid+1,r,k);
        return rt;
    }
    int query(int L,int R,int l,int r,int k)
    {
        if(l>=r)return l;
        int x=sum[lc[R]]-sum[lc[L]],mid=(l+r)/2;
        if(x>=k)return query(lc[L],lc[R],l,mid,k);
        return query(rc[L],rc[R],mid+1,r,k-x);
    }
    int main()
    {
        scanf("%d%d",&n,&Q);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]),b[i]=a[i];
        sort(b+1,b+n+1);
        m=unique(b+1,b+n+1)-b-1;
        for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+m+1,a[i])-b;
        root[0]=build(1,m);
        for(int i=1;i<=n;i++)root[i]=update(root[i-1],1,m,a[i]);
        while(Q--)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            printf("%d
    ",b[query(root[x-1],root[y],1,m,z)]);
        }
    }

    可持久化并查集https://www.luogu.org/problemnew/show/P3402

    #include<bits/stdc++.h>
    using namespace std;
    const int N=2e5+7;
    int n,m,tot,root[N],fa[N*30],dep[N*30],lc[N*30],rc[N*30];
    void build(int&rt,int l,int r)
    {
        rt=++tot;
        if(l==r){fa[rt]=l;return;}
        int mid=(l+r)/2;
        build(lc[rt],l,mid);
        build(rc[rt],mid+1,r);
    }
    void update(int&rt,int prt,int l,int r,int pos,int f)
    {
        rt=++tot;
        if(l==r){fa[rt]=f,dep[rt]=dep[prt];return;}
        lc[rt]=lc[prt],rc[rt]=rc[prt];
        int mid=(l+r)/2;
        if(pos<=mid)update(lc[rt],lc[prt],l,mid,pos,f);
        else update(rc[rt],rc[prt],mid+1,r,pos,f);
    }
    int query(int rt,int l,int r,int pos)
    {
        if(l==r)return rt;
        int mid=(l+r)/2;
        if(pos<=mid)return query(lc[rt],l,mid,pos);
        return query(rc[rt],mid+1,r,pos);
    }
    int find_fa(int rt,int x)
    {
        int y=query(rt,1,n,x);
        if(x==fa[y])return y;
        return find_fa(rt,fa[y]);
    }
    void add(int rt,int l,int r,int pos)
    {
        if(l==r){dep[rt]++;return;}
        int mid=(l+r)/2;
        if(pos<=mid)add(lc[rt],l,mid,pos);
        else add(rc[rt],mid+1,r,pos);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        build(root[0],1,n);
        for(int i=1,op,x,y;i<=m;i++)
        {
            scanf("%d%d",&op,&x);
            if(op==1)
            {
                scanf("%d",&y);
                root[i]=root[i-1];
                x=find_fa(root[i],x);
                y=find_fa(root[i],y);
                if(fa[x]==fa[y])continue;
                if(dep[x]>dep[y])swap(x,y);
                update(root[i],root[i-1],1,n,fa[x],fa[y]);
                if(dep[x]==dep[y])add(root[i],1,n,fa[y]);
            }
            else if(op==2)root[i]=root[x];
            else{
                scanf("%d",&y);
                root[i]=root[i-1];
                x=find_fa(root[i],x);
                y=find_fa(root[i],y);
                if(fa[x]==fa[y])puts("1");else puts("0");
            }
        }
    }

    线段树合并https://www.lydsy.com/JudgeOnline/problem.php?id=2212

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=5e6+77;
    int n,lc[N],rc[N],cnt[N],tot=0;
    ll ans;
    int merge(int rt1,int rt2,int l,int r,ll&s1,ll&s2)
    {
        if(!rt1||!rt2)return rt1+rt2;
        if(l==r){cnt[rt1]+=cnt[rt2];return rt1;}
        int mid=(l+r)/2;
        s1+=1ll*cnt[rc[rt1]]*cnt[lc[rt2]];
        s2+=1ll*cnt[rc[rt2]]*cnt[lc[rt1]];
        lc[rt1]=merge(lc[rt1],lc[rt2],l,mid,s1,s2);
        rc[rt1]=merge(rc[rt1],rc[rt2],mid+1,r,s1,s2);
        cnt[rt1]=cnt[lc[rt1]]+cnt[rc[rt1]];
        return rt1;
    }
    int build(int l,int r,int k)
    {
        int x=++tot;
        if(l==r){cnt[x]=1;return x;}
        int mid=(l+r)/2;
        if(k<=mid)lc[x]=build(l,mid,k);
        else rc[x]=build(mid+1,r,k);
        cnt[x]=cnt[lc[x]]+cnt[rc[x]];
        return x;
    }
    int dfs()
    {
        int x;
        scanf("%d",&x);
        if(x)return build(1,n,x);
        ll s1=0,s2=0;
        int u=dfs(),v=dfs(),rt=merge(u,v,1,n,s1,s2);
        ans+=min(s1,s2);
        return rt;
    }
    int main()
    {
        scanf("%d",&n);
        dfs();
        printf("%lld",ans);
    }

    树上启发式合并https://www.luogu.org/problemnew/show/P3302

    #include<bits/stdc++.h>
    using namespace std;
    const int N=80100;
    int n,m,p,a[N],b[N],rt[N],sz[N],fa[N],dep[N],f[N][20];
    vector<int>G[N];
    namespace tree{
        struct seg{int lc,rc,s;}tr[N*400];
        int sz;
        void update(int k,int l,int r,int&rt,int prt)
        {
            tr[rt=++sz]=tr[prt],tr[rt].s++;
            if(l==r)return;
            int mid=l+r>>1;
            if(k<=mid)update(k,l,mid,tr[rt].lc,tr[prt].lc);
            else update(k,mid+1,r,tr[rt].rc,tr[prt].rc);
        }
        int query(int u,int v,int pu,int pv,int k,int l,int r)
        {
            if(l==r)return l;
            int mid=l+r>>1,sum=tr[tr[u].lc].s+tr[tr[v].lc].s-tr[tr[pu].lc].s-tr[tr[pv].lc].s;
            if(k<=sum)return query(tr[u].lc,tr[v].lc,tr[pu].lc,tr[pv].lc,k,l,mid);
            return query(tr[u].rc,tr[v].rc,tr[pu].rc,tr[pv].rc,k-sum,mid+1,r);
        }
    }
    int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
    void dfs(int u,int Fa,int anc)
    {
        f[u][0]=Fa;
        for(int i=1;i<=19;i++)f[u][i]=f[f[u][i-1]][i-1];
        sz[anc]++,dep[u]=dep[Fa]+1,fa[u]=Fa;
        int x=lower_bound(b+1,b+p+1,a[u])-b;
        tree::update(x,1,p,rt[u],rt[Fa]);
        for(int i=0;i<G[u].size();i++)if(G[u][i]!=Fa)dfs(G[u][i],u,anc);
    }
    int lca(int x,int y)
    {
        if(dep[x]<dep[y])swap(x,y);
        int t=dep[x]-dep[y];
        for(int i=0;(1<<i)<=t;i++)if(t&(1<<i))x=f[x][i];
        if(x==y)return x;
        for(int i=19;~i;i--)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
        return f[x][0];
    }
    int main()
    {
        int Q;scanf("%*d%d%d%d",&n,&m,&Q);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]),b[i]=a[i],fa[i]=i;
        for(int i=1,x,y;i<=m
        ;i++)scanf("%d%d",&x,&y),G[x].push_back(y),G[y].push_back(x);
        sort(b+1,b+n+1);
        p=unique(b+1,b+n+1)-b-1;
        for(int i=1;i<=n;i++)if(!dep[i])dfs(i,0,i),fa[i]=i;
        char op;
        int x,y,z,ans=0;
        while(Q--)
        {
            scanf(" %c%d%d",&op,&x,&y),x^=ans,y^=ans;
            if(op=='Q')
            {
                scanf("%d",&z),z^=ans;
                int Fa=lca(x,y);
                printf("%d
    ",ans=b[tree::query(rt[x],rt[y],rt[Fa],rt[f[Fa][0]],z,1,p)]);
            }
            else{
                G[x].push_back(y),G[y].push_back(x);
                int fx=find(x),fy=find(y);
                if(sz[fx]<sz[fy])swap(x,y),swap(fx,fy);
                dfs(y,x,fx);
            }
        }
    }

    可持久化Triehttps://www.luogu.org/problemnew/show/P4098

    #include<bits/stdc++.h>
    using namespace std;
    typedef pair<int,int>pii;
    const int N=50005;
    int n,cnt,ans,a[N],rt[N],ch[N*32][2],sz[N*32],L[N],R[N];
    pii b[N];
    void build(int x,int id)
    {
        int u,v=rt[id-1];u=rt[id]=++cnt;
        sz[u]=sz[v]+1;
        for(int i=29;~i;i--)
        {
            int c=x>>i&1;
            ch[u][c^1]=ch[v][c^1],ch[u][c]=++cnt;
            u=ch[u][c],v=ch[v][c],sz[u]=sz[v]+1;
        }
    }
    int query(int x,int l,int r)
    {
        if(l>r)return 0;
        l=rt[l-1],r=rt[r];
        int ret=0;
        for(int i=29;~i;i--)
        {
            int c=x>>i&1;
            if(sz[ch[r][c^1]]-sz[ch[l][c^1]])ret+=1<<i,l=ch[l][c^1],r=ch[r][c^1];
            else l=ch[l][c],r=ch[r][c];
        }
        return ret;
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]),build(a[i],i),b[i]=pii(a[i],i),L[i]=i-1,R[i]=i+1;
        sort(b+1,b+n+1);
        for(int i=1;i<=n;i++)
        {
            int x=b[i].second,l=L[x],r=R[x];L[r]=l,R[l]=r;
            if(l)ans=max(ans,query(a[x],L[l]+1,r-1));
            if(r)ans=max(ans,query(a[x],l+1,R[r]-1));
        }
        printf("%d",ans);
    }

    动态开点线段树https://www.lydsy.com/JudgeOnline/problem.php?id=3939

    #include<bits/stdc++.h>
    #define lson l,mid,lc[rt]
    #define rson mid+1,r,rc[rt]
    using namespace std;
    const int N=760,M=N*N*15,mod=1e9+7;
    int n,m,k,cnt,a[N][N],f[N][N],s[N][N],sum[M],root[N*N],lc[M],rc[M];
    void insert(int k,int c,int l,int r,int &rt)
    {
        if(!rt)rt=++cnt;
        if(l==r){sum[rt]=(sum[rt]+c)%mod;return;}
        int mid=(l+r)/2;
        if(k<=mid)insert(k,c,lson);
        else insert(k,c,rson);
        sum[rt]=(sum[lc[rt]]+sum[rc[rt]])%mod;
    }
    int query(int L,int R,int l,int r,int rt)
    {
        if(!rt)return 0;
        if(L<=l&&r<=R)return sum[rt];
        int mid=(l+r)/2,ret=0;
        if(L<=mid)ret+=query(L,R,lson);
        if(R>mid)ret=(ret+query(L,R,rson))%mod;
        return ret;
    }
    int main()
    {
        scanf("%d%d%d",&n,&m,&k);
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        scanf("%d",&a[i][j]);
        f[1][1]=1;
        for(int i=1;i<=m;i++)s[1][i]=1;
        for(int i=2;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            f[i][j]=s[i-1][j-1];
            if(j>1)f[i][j]=(f[i][j]-query(1,j-1,1,m,root[a[i][j]])+mod)%mod;
            s[i][j]=(1ll*s[i][j-1]+s[i-1][j]-s[i-1][j-1]+f[i][j]+mod)%mod;
            insert(j,f[i-1][j],1,m,root[a[i-1][j]]);
        }
        printf("%d",f[n][m]);
    }

    treaphttps://www.luogu.org/problemnew/show/P3369

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+7;
    int n,cnt,root,ans,lc[N],rc[N],sz[N],w[N],rnd[N],v[N];
    void update(int rt){sz[rt]=sz[lc[rt]]+sz[rc[rt]]+w[rt];}
    void rturn(int&rt)
    {
        int t=lc[rt];
        lc[rt]=rc[t];rc[t]=rt;
        sz[t]=sz[rt];update(rt);rt=t;
    }
    void lturn(int&rt)
    {
        int t=rc[rt];
        rc[rt]=lc[t];lc[t]=rt;
        sz[t]=sz[rt];update(rt);rt=t;
    }
    void insert(int&rt,int val)
    {
        if(!rt)
        {
            rt=++cnt;
            sz[rt]=w[rt]=1;
            v[rt]=val;rnd[rt]=rand();
            return;
        }
        sz[rt]++;
        if(v[rt]==val)w[rt]++;
        else if(v[rt]>val){insert(lc[rt],val);if(rnd[lc[rt]]<rnd[rt])rturn(rt);}
        else{insert(rc[rt],val);if(rnd[rc[rt]]<rnd[rt])lturn(rt);}
    }
    void del(int&rt,int val)
    {
        if(!rt)return;
        if(v[rt]==val)
        {
            if(w[rt]>1){w[rt]--;sz[rt]--;return;}
            if(lc[rt]*rc[rt]==0)rt=lc[rt]+rc[rt];
            else if(rnd[lc[rt]]<rnd[rc[rt]])rturn(rt),del(rt,val);
            else lturn(rt),del(rt,val);
            return;
        }
        sz[rt]--;
        if(v[rt]>val)del(lc[rt],val);
        else del(rc[rt],val);
    }
    int query_rank(int rt,int val)
    {
        if(!rt)return 0;
        if(v[rt]==val)return sz[lc[rt]]+1;
        if(v[rt]>val)return query_rank(lc[rt],val);
        return sz[lc[rt]]+w[rt]+query_rank(rc[rt],val);
    }
    int query_num(int rt,int rnk)
    {
        if(!rt)return 0;
        if(rnk<=sz[lc[rt]])return query_num(lc[rt],rnk);
        if(rnk>sz[lc[rt]]+w[rt])return query_num(rc[rt],rnk-sz[lc[rt]]-w[rt]);
        return v[rt];
    }
    void query_pre(int rt,int val)
    {
        if(!rt)return;
        if(v[rt]<val)ans=rt,query_pre(rc[rt],val);
        else query_pre(lc[rt],val);
    }
    void query_sub(int rt,int val)
    {
        if(!rt)return;
        if(v[rt]>val)ans=rt,query_sub(lc[rt],val);
        else query_sub(rc[rt],val);
    }
    int main()
    {
        srand(time(0));
        scanf("%d",&n);
        for(int i=1,op,x;i<=n;i++)
        {
            scanf("%d%d",&op,&x);
            if(op==1)insert(root,x);
            if(op==2)del(root,x);
            if(op==3)printf("%d
    ",query_rank(root,x));
            if(op==4)printf("%d
    ",query_num(root,x));
            if(op==5)ans=0,query_pre(root,x),printf("%d
    ",v[ans]);
            if(op==6)ans=0,query_sub(root,x),printf("%d
    ",v[ans]);
        }
    }

    splayhttps://www.luogu.org/problemnew/show/P3391

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+7;
    int n,m,root,sz[N],fa[N],ch[N][2];
    bool rev[N];
    void pushup(int rt){sz[rt]=sz[ch[rt][0]]+sz[ch[rt][1]]+1;}
    void pushdown(int rt)
    {
        if(rev[rt])
        {
            swap(ch[rt][0],ch[rt][1]);
            rev[rt]=0;
            rev[ch[rt][0]]^=1,rev[ch[rt][1]]^=1;
        }
    }
    void rotate(int&rt,int x)
    {
        int y=fa[x],z=fa[y];
        bool dy=ch[y][1]==x,dz=ch[z][1]==y;
        pushdown(y);
        if(y==rt)rt=x;else ch[z][dz]=x;
        fa[x]=z;
        ch[y][dy]=ch[x][dy^1],fa[ch[x][dy^1]]=y;
        ch[x][dy^1]=y,fa[y]=x;
        pushup(y);
    }
    void splay(int&rt,int x)
    {
        pushdown(x);
        while(x!=rt)
        {
            int y=fa[x],z=fa[y];
            if(y!=rt)
            {
                if((ch[y][1]==x)^(ch[z][1]==y))rotate(rt,x);
                else rotate(rt,y);
            }
            rotate(rt,x);
        }
        pushup(x);
    }
    int find(int rt,int x)
    {
        if(!rt)return 0;
        pushdown(rt);
        if(x<=sz[ch[rt][0]])return find(ch[rt][0],x);
        if(x==sz[ch[rt][0]]+1)return rt;
        return find(ch[rt][1],x-sz[ch[rt][0]]-1);
    }
    void print(int rt)
    {
        if(!rt)return;
        pushdown(rt);
        print(ch[rt][0]);
        if(rt>1&&rt<n+2)printf("%d ",rt-1);
        print(ch[rt][1]);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n+2;++i)sz[i]=n+3-i,fa[i]=i-1,ch[i][1]=i+1;
        ch[n+2][1]=0,root=1;
        while(m--)
        {
            int l,r;
            scanf("%d%d",&l,&r);
            splay(root,find(root,l));
            splay(ch[root][1],find(root,r+2));
            rev[ch[ch[root][1]][0]]^=1;
        }
        print(root);
    }

    替罪羊树https://www.lydsy.com/JudgeOnline/problem.php?id=3065

    #include<bits/stdc++.h>
    #define pb push_back
    using namespace std;
    const int N=71000,M=1e7+7;
    const double alpha=0.75;
    int n,m,sz,ans,root,tmp,v[N],dfn[N],rt[N],lc[N],rc[N];
    struct seg{int l,r,sum;}a[M];
    vector<int>rec,t,p;
    int newnode()
    {
        if(!rec.size())return++sz;
        int k=rec.back();rec.pop_back();
        return k;
    }
    void reclaim(int&x)
    {
        if(!x)return;
        rec.pb(x);
        reclaim(a[x].l);reclaim(a[x].r);
        a[x].sum=0;x=0;
    }
    void insert(int &k,int l,int r,int p,int v)
    {
        if(!k)k=newnode();
        if(l==r){a[k].sum+=v;return;}
        int mid=(l+r)/2;
        if(p<=mid)insert(a[k].l,l,mid,p,v);
        else insert(a[k].r,mid+1,r,p,v);
        a[k].sum=a[a[k].l].sum+a[a[k].r].sum;
        if(!a[k].sum)reclaim(k);
    }
    void build(int &k,int l,int r)
    {
        if(l>r)return;
        if(l==r)
        {
            k=dfn[l];insert(rt[k],0,70000,v[k],1);return;
        }
        int mid=(l+r)/2;k=dfn[mid];
        build(lc[k],l,mid-1);build(rc[k],mid+1,r);
        for(int i=l;i<=r;i++)insert(rt[k],0,70000,v[dfn[i]],1);
    }
    void del(int &x)
    {
        if(!x)return;reclaim(rt[x]);
        del(lc[x]);p.pb(x);del(rc[x]);
        x=0;
    }
    void rebuild(int&x)
    {
        del(x);
        int s1=p.size();
        for(int i=1;i<=s1;i++)dfn[i]=p[i-1];
        build(x,1,s1);
        p.clear();
    }
    int update(int k,int x,int val)
    {
        insert(rt[k],0,70000,val,1);
        int t,L=a[rt[lc[k]]].sum;
        if(L+1==x)t=v[k],v[k]=val;
        else if(L>=x)t=update(lc[k],x,val);
        else t=update(rc[k],x-L-1,val);
        insert(rt[k],0,70000,t,-1);
        return t;
    }
    void query(int k,int l,int r)
    {
        int L=a[rt[lc[k]]].sum,R=a[rt[k]].sum;
        if(l==1&&r==R){t.pb(rt[k]);return;}
        if(l<=L+1&&L+1<=r)p.pb(v[k]);
        if(r<=L)query(lc[k],l,r);
        else if(l>L+1)query(rc[k],l-L-1,r-L-1);
        else{
            if(l<=L)query(lc[k],l,L);
            if(R>L+1)query(rc[k],1,r-L-1);
        }
    }
    int solve(int L,int R,int k)
    {
        query(root,L,R);
        k--;
        int l=0,r=70000,s1=t.size(),s2=p.size();
        while(l<r)
        {
            int mid=(l+r)/2,sum=0;
            for(int i=0;i<s1;i++)sum+=a[a[t[i]].l].sum;
            for(int i=0;i<s2;i++)if(p[i]>=l&&p[i]<=mid)sum++;
            if(k<sum)
            {
                for(int i=0;i<s1;i++)t[i]=a[t[i]].l;
                r=mid;
            }
            else{
                for(int i=0;i<s1;i++)t[i]=a[t[i]].r;
                l=mid+1;k-=sum;
            }
        }
        t.clear();p.clear();
        return l;
    }
    void insert(int&k,int x,int val)
    {
        if(!k)
        {
            k=++n;
            insert(rt[k],0,70000,val,1);
            v[k]=val;
            return;
        }
        insert(rt[k],0,70000,val,1);
        int L=a[rt[lc[k]]].sum;
        if(L>=x)insert(lc[k],x,val);
        else insert(rc[k],x-L-1,val);
        if(a[rt[k]].sum*alpha>max(a[rt[lc[k]]].sum,a[rt[rc[k]]].sum))
        {
            if(!tmp)return;
            if(lc[k]==tmp)rebuild(lc[k]);else rebuild(rc[k]);
            tmp=0;
        }
        else tmp=k;
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&v[i]);
        for(int i=1;i<=n;i++)dfn[i]=i;
        build(root,1,n);
        scanf("%d",&m);
        char ch;int x,y,K;
        while(m--)
        {
            scanf(" %c%d%d",&ch,&x,&y);
            x^=ans;y^=ans;
            if(ch=='Q')scanf("%d",&K),K^=ans,printf("%d
    ",ans=solve(x,y,K));
            else if(ch=='M')update(root,x,y);
            else{
                tmp=0;
                insert(root,x-1,y);
                if(tmp)tmp=0,rebuild(root);
            }
        }
    }

    长链剖分https://www.luogu.org/problemnew/show/P4292

    #include<bits/stdc++.h>
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    using namespace std;
    const int N=2e5+7;
    int n,L,R,cnt,tot,hd[N],v[N],nxt[N],w[N],son[N],sv[N],dep[N],dfn[N];
    double mid,ans,s[N<<2],val[N],f[N];
    void add(int x,int y,int z){v[++tot]=y,nxt[tot]=hd[x],w[tot]=z,hd[x]=tot;}
    void dfs1(int u,int fa)
    {
        for(int i=hd[u];i;i=nxt[i])
        if(v[i]!=fa)
        {
            dfs1(v[i],u);
            if(dep[v[i]]>=dep[son[u]])son[u]=v[i],sv[u]=w[i];
            if(dep[v[i]]+1>dep[u])dep[u]=dep[v[i]]+1;
        }
    }
    void dfs2(int u,int fa)
    {
        dfn[u]=++cnt;
        if(son[u])dfs2(son[u],u);
        for(int i=hd[u];i;i=nxt[i])if(v[i]!=fa&&v[i]!=son[u])dfs2(v[i],u);
    }
    void update(int k,double v,int l,int r,int rt)
    {
        if(l==r){s[rt]=max(s[rt],v);return;}
        int mid=l+r>>1;
        if(k<=mid)update(k,v,lson);else update(k,v,rson);
        s[rt]=max(s[rt<<1],s[rt<<1|1]);
    }
    double query(int L,int R,int l,int r,int rt)
    {
        if(L<=l&&r<=R)return s[rt];
        int mid=l+r>>1;double ret=-2e9;
        if(L<=mid)ret=max(ret,query(L,R,lson));
        if(R>mid)ret=max(ret,query(L,R,rson));
        return ret;
    }
    void dfs(int u,int fa)
    {
        int id=dfn[u];
        if(son[u])dfs(son[u],u),val[id]=val[id+1]+sv[u]-mid;
        update(id,f[id]=-val[id],1,n,1);
        if(dep[u]>=L)
        {
            double tmp=query(id+L,id+min(dep[u],R),1,n,1);
            ans=max(ans,tmp+val[id]);
        }
        for(int i=hd[u];i;i=nxt[i])
        if(v[i]!=fa&&v[i]!=son[u])
        {
            int idv=dfn[v[i]];
            dfs(v[i],u);
            for(int j=0;j<=dep[v[i]];j++)
            {
                int l=id+max(0,L-j-1),r=id+min(dep[u],R-j-1);
                double tmp=query(l,r,1,n,1);
                ans=max(ans,tmp+val[idv]+val[id]+f[idv+j]+w[i]-mid);
            }
            for(int j=0;j<=dep[v[i]];++j)
            {
                double tmp=val[idv]+f[idv+j]+w[i]-mid-val[id];
                if(tmp>f[id+j+1])update(id+j+1,f[id+j+1]=tmp,1,n,1);
            }
        }
    }
    bool check()
    {
        for(int i=0;i<(N<<2);i++)s[i]=-2e9;
        ans=-2e9,dfs(1,0);
        return ans>=1e-4;
    }
    int main()
    {
        scanf("%d%d%d",&n,&L,&R);
        for(int i=1,x,y,z;i<n;i++)scanf("%d%d%d",&x,&y,&z),add(x,y,z),add(y,x,z);
        dfs1(1,0),dfs2(1,0);
        double l=0,r=1e6;
        while(r-l>1e-4)
        {
            mid=(l+r)/2;
            if(check())l=mid;else r=mid;
        }
        printf("%.3lf",l);
    }

    fhq-treaphttps://www.luogu.org/problemnew/show/CF702F

    #include<bits/stdc++.h>
    using namespace std;
    const int N=2e5+7;
    int n,m,root,val[N],cnt[N],tv[N],tc[N],rd[N],ch[N][2];
    pair<int,int>a[N];
    void pushdown(int x)
    {
        if(!x)return;
        int lc=ch[x][0],rc=ch[x][1];
        if(tv[x])
        {
            val[lc]+=tv[x],val[rc]+=tv[x];
            tv[lc]+=tv[x],tv[rc]+=tv[x];
            tv[x]=0;
        }
        if(tc[x])
        {
            cnt[lc]+=tc[x],cnt[rc]+=tc[x];
            tc[lc]+=tc[x],tc[rc]+=tc[x];
            tc[x]=0;
        }
    }
    void split(int rt,int&x,int&y,int v)
    {
        if(!rt){x=y=0;return;}
        pushdown(rt);
        if(val[rt]<v)x=rt,split(ch[rt][1],ch[x][1],y,v);
        else y=rt,split(ch[rt][0],x,ch[y][0],v);
    }
    int merge(int x,int y)
    {
        if(!x||!y)return x+y;
        if(rd[x]<rd[y])
        {
            pushdown(x),ch[x][1]=merge(ch[x][1],y);
            return x;
        }
        else{
            pushdown(y),ch[y][0]=merge(x,ch[y][0]);
            return y;
        }
    }
    int insert(int x,int y)
    {
        int r1=0,r2=0;
        split(x,r1,r2,val[y]);
        r1=merge(r1,y),x=merge(r1,r2);
        return x;
    }
    int dfs(int x,int y)
    {
        if(!x)return y;
        pushdown(x);
        y=dfs(ch[x][0],y),y=dfs(ch[x][1],y);
        ch[x][0]=ch[x][1]=0;
        return insert(y,x);
    }
    void down(int x)
    {
        if(!x)return;
        pushdown(x),down(ch[x][0]),down(ch[x][1]);
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1,x,y;i<=n;i++)scanf("%d%d",&x,&y),a[i]=make_pair(-y,x);
        sort(a+1,a+n+1);
        scanf("%d",&m);
        for(int i=1;i<=m;i++)scanf("%d",&val[i]),rd[i]=rand(),root=insert(root,i);
        for(int i=1;i<=n;i++)
        {
            int c=a[i].second,r1=0,r2=0,r3=0,r4=0;
            split(root,r1,r2,c);
            val[r2]-=c,tv[r2]-=c;
            cnt[r2]++,tc[r2]++;
            split(r2,r3,r4,c-1);
            r1=dfs(r3,r1),root=merge(r1,r4);
        }
        down(root);
        for(int i=1;i<=m;i++)printf("%d ",cnt[i]);
    }

    笛卡尔树https://www.luogu.org/problemnew/show/SP3734

    #include<bits/stdc++.h>
    using namespace std;
    const int N=525,M=1e6+7,mod=1e9+7;
    int n,m,top,f[N][N],g[N],fac[M],inv[M],v[N],st[N],fa[N],ch[N][2];
    int C(int a,int b){return a<b?0:1ll*fac[a]*inv[b]%mod*inv[a-b]%mod;}
    int dfs(int x)
    {
        int a=1,b=v[x]-v[fa[x]],y,s;
        f[x][0]=1;
        for(int i=0;i<2;i++)
        if(ch[x][i])
        {
            y=ch[x][i],s=dfs(y);
            memset(g,0,sizeof g);
            for(int j=0;j<=a;j++)
            for(int k=0;k<=s&&j+k<=m;k++)
            g[j+k]=(g[j+k]+1ll*f[x][j]*f[y][k])%mod;
            a+=s;
            for(int j=0;j<=a;j++)f[x][j]=g[j];
        }
        for(int i=min(m,a);~i;i--)
        {
            s=0;
            for(int j=0;j<=i;j++)s=(s+1ll*f[x][i-j]*fac[j]%mod*C(a-i+j,j)%mod*C(b,j))%mod;
            f[x][i]=s;
        }
        return a;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%d",&v[i]);
        fac[0]=1;for(int i=1;i<M;i++)fac[i]=1ll*fac[i-1]*i%mod;
        inv[0]=inv[1]=1;for(int i=2;i<M;i++)inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
        for(int i=2;i<M;i++)inv[i]=1ll*inv[i-1]*inv[i]%mod;
        for(int i=1;i<=n;i++)
        {
            while(top&&v[st[top]]>v[i])
            {
                int x=st[top--];
                if(top&&v[st[top]]>v[i])ch[st[top]][1]=x,fa[x]=st[top];
                else ch[i][0]=x,fa[x]=i;
            }
            st[++top]=i;
        }
        while(top>1)ch[st[top-1]][1]=st[top],fa[st[top]]=st[top-1],top--;
        dfs(st[1]);
        printf("%d",f[st[1]][m]);
    }

    树套树https://www.lydsy.com/JudgeOnline/problem.php?id=3489

    #include<bits/stdc++.h>
    #define lson l,mid,ch[rt][0]
    #define rson mid+1,r,ch[rt][1]
    using namespace std;
    const int N=1e5+7,M=4e7+7;
    typedef long long ll;
    struct node{int x,y,z,v;};
    int n,m,tot,ans,a[N],pre[N],nxt[N],lst[N],rt[N],ch[M][2],v[M];
    node p[N];
    bool operator<(node x,node y){return x.x<y.x;}
    void change(int prt,int l,int r,int&rt,node c)
    {
        rt=++tot;
        memcpy(ch[rt],ch[prt],sizeof ch[rt]);
        v[rt]=max(v[prt],c.v);
        if(l==r)return;
        int mid=l+r>>1;
        if(c.z<=mid)change(ch[prt][0],lson,c);
        else change(ch[prt][1],rson,c);
    }
    void modify(int prt,int l,int r,int&rt,node c)
    {
        rt=++tot;
        memcpy(ch[rt],ch[prt],sizeof ch[rt]);
        change(v[prt],1,n+2,v[rt],c);
        if(l==r)return;
        int mid=l+r>>1;
        if(c.y<=mid)modify(ch[prt][0],lson,c);
        else modify(ch[prt][1],rson,c);
    }
    int ask(int L,int R,int l,int r,int rt)
    {
        if(!rt)return 0;
        if(L<=l&&r<=R)return v[rt];
        int mid=l+r>>1,ret=0;
        if(L<=mid)ret=max(ret,ask(L,R,lson));
        if(R>mid)ret=max(ret,ask(L,R,rson));
        return ret;
    }
    int query(int L,int R,int l,int r,int rt,int ql,int qr)
    {
        if(!rt)return 0;
        if(L<=l&&r<=R)return ask(ql,qr,1,n+2,v[rt]);
        int mid=l+r>>1,ret=0;
        if(L<=mid)ret=max(ret,query(L,R,lson,ql,qr));
        if(R>mid)ret=max(ret,query(L,R,rson,ql,qr));
        return ret;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)lst[i]=1;
        for(int i=2;i<=n+1;i++)scanf("%d",&a[i]),nxt[lst[a[i]]]=i,pre[i]=lst[a[i]],lst[a[i]]=i;
        for(int i=1;i<=n;i++)nxt[lst[i]]=n+2;
        for(int i=2;i<=n+1;i++)p[i-1]=(node){pre[i],nxt[i],i,a[i]};
        sort(p+1,p+n+1);
        for(int i=1,pos=1;i<=n+2;i++)
        {
            rt[i]=rt[i-1];
            while(p[pos].x==i&&pos<=n)modify(rt[i],1,n+2,rt[i],p[pos++]);
        }
        while(m--)
        {
            int x,y,l,r;
            scanf("%d%d",&x,&y);
            x=(x+ans)%n+2,y=(y+ans)%n+2,l=min(x,y),r=max(x,y);
            printf("%d
    ",ans=query(r+1,n+2,1,n+2,rt[l-1],l,r));
        }
    }

    LCThttps://www.luogu.org/problemnew/show/P3203

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=2e5+7;
    int n,fa[N],ch[N][2],nxt[N],st[N],sz[N],rev[N];
    bool isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
    void pushup(int x){sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;}
    void pushdown(int x)
    {
        int l=ch[x][0],r=ch[x][1];
        if(rev[x])rev[x]^=1,rev[l]^=1,rev[r]^=1,swap(ch[x][0],ch[x][1]);
    }
    void rotate(int x)
    {
        int y=fa[x],z=fa[fa[x]],l;
        l=(ch[y][1]==x);
        if(!isroot(y))
        {
            if(ch[z][0]==y)ch[z][0]=x;
            else ch[z][1]=x;
        }
        fa[x]=z,fa[y]=x;
        fa[ch[x][l^1]]=y;
        ch[y][l]=ch[x][l^1],ch[x][l^1]=y;
        pushup(y),pushup(x);
    }
    void splay(int x)
    {
        st[1]=x;
        int top=1;
        for(int i=x;!isroot(i);i=fa[i])st[++top]=fa[i];
        for(int i=top;i;i--)pushdown(st[i]);
        while(!isroot(x))
        {
            int y=fa[x],z=fa[fa[x]];
            if(!isroot(y))
            {
                if((ch[y][0]==x)^(ch[z][0]==y))rotate(x);
                else rotate(y);
            }
            rotate(x);
        }
    }
    void access(int x)
    {
        int t=0;
        while(x)splay(x),ch[x][1]=t,t=x,x=fa[x];
    }
    void reverse(int x){access(x),splay(x),rev[x]^=1;}
    void link(int x,int y){reverse(x),fa[x]=y,splay(x);}
    void cut(int x,int y){reverse(x),access(y),splay(y),ch[y][0]=fa[x]=0;}
    int main()
    {
        scanf("%d",&n);
        int op,x,y,Q;
        for(int i=1;i<=n;i++)scanf("%d",&x),fa[i]=min(x+i,n+1),sz[i]=1,nxt[i]=fa[i];
        sz[n+1]=1;
        scanf("%d",&Q);
        while(Q--)
        {
            scanf("%d%d",&op,&x);
            x++;
            if(op==1)reverse(n+1),access(x),splay(x),printf("%d
    ",sz[ch[x][0]]);
            else scanf("%d",&y),cut(x,nxt[x]),link(x,min(x+y,n+1)),nxt[x]=min(x+y,n+1);
        }
    }

    KD-Treehttps://www.lydsy.com/JudgeOnline/problem.php?id=2850

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=50010,inf=2e9;
    struct Node{int mx[2],mn[2],d[2],lc,rc,v;ll s;}t[maxn],x;
    int D,n,m,rt,a,b,c;
    bool operator<(Node a,Node b){return a.d[D]<b.d[D];}
    void update(int k)
    {
        t[k].s=t[t[k].lc].s+t[t[k].rc].s+t[k].v;
        for(int i=0;i<2;i++)
        {
            t[k].mn[i]=min(min(t[t[k].lc].mn[i],t[t[k].rc].mn[i]),t[k].d[i]);
            t[k].mx[i]=max(max(t[t[k].lc].mx[i],t[t[k].rc].mx[i]),t[k].d[i]);
        }
    }
    void build(int&k,int l,int r,int cur)
    {
        k=0;
        if(l>r)return;
        D=cur;
        int mid=(l+r)/2;
        nth_element(t+l,t+mid,t+r+1);
        k=mid;
        build(t[k].lc,l,mid-1,cur^1);
        build(t[k].rc,mid+1,r,cur^1);
        update(k);
    }
    bool inner(int x,int y){return 1ll*a*x+1ll*b*y<c;}
    int check(int k)
    {
        int cnt=0;
        if(inner(t[k].mn[0],t[k].mn[1]))cnt++;
        if(inner(t[k].mn[0],t[k].mx[1]))cnt++;
        if(inner(t[k].mx[0],t[k].mn[1]))cnt++;
        if(inner(t[k].mx[0],t[k].mx[1]))cnt++;
        if(!cnt)return 0;
        if(cnt==4)return 1;
        return -1;
    }
    ll query(int k)
    {
        if(!k)return 0;
        int f=check(k);
        if(!f)return 0;
        if(f==1)return t[k].s;
        return query(t[k].lc)+query(t[k].rc)+t[k].v*inner(t[k].d[0],t[k].d[1]);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        t[0].mn[0]=t[0].mn[1]=1e9;
        t[0].mx[0]=t[0].mx[1]=-1e9;
        for(int i=1;i<=n;i++)scanf("%d%d%d",&t[i].d[0],&t[i].d[1],&t[i].v);
        build(rt,1,n,0);
        while(m--)scanf("%d%d%d",&a,&b,&c),printf("%lld
    ",query(rt));
    }

    线段树优化建图https://www.luogu.org/problemnew/show/CF786B

    #include<bits/stdc++.h>
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    typedef long long ll;
    using namespace std;
    typedef pair<int,int>pii;
    const int N=1e5+7;
    struct node{int u;ll d;};
    int n,m,S,tot,id[2][N<<2],vis[N*5];
    ll d[N*5];
    vector<pii>G[N*5];
    vector<int>vec;
    bool operator<(node a,node b){return a.d>b.d;}
    priority_queue<node>q;
    void adde(int u,int v,int w){G[u].push_back(pii(v,w));}
    void build(int l,int r,int rt,int k)
    {
        id[k][rt]=++tot;
        if(l==r)
        {
            if(!k)adde(id[k][rt],l,0);else adde(l,id[k][rt],0);
            return;
        }
        int mid=l+r>>1;
        build(lson,k),build(rson,k);
        if(!k)adde(id[k][rt],id[k][rt<<1],0),adde(id[k][rt],id[k][rt<<1|1],0);
        else adde(id[k][rt<<1],id[k][rt],0),adde(id[k][rt<<1|1],id[k][rt],0);
    }
    void query(int L,int R,int k,int l,int r,int rt)
    {
        if(L<=l&&r<=R){vec.push_back(id[k][rt]);return;}
        int mid=l+r>>1;
        if(L<=mid)query(L,R,k,lson);
        if(R>mid)query(L,R,k,rson);
    }
    void dijkstra(int S)
    {
        for(int i=1;i<=5*n;i++)d[i]=1e18,vis[i]=0;
        q.push((node){S,0}),d[S]=0;
        while(!q.empty())
        {
            int u=q.top().u;q.pop();
            if(vis[u])continue;
            vis[u]=1;
            for(int i=0;i<G[u].size();i++)
            {
                int v=G[u][i].first,w=G[u][i].second;
                if(d[v]>d[u]+w)d[v]=d[u]+w,q.push((node){v,d[v]});
            }
        }
    }
    int main()
    {
        scanf("%d%d%d",&n,&m,&S);
        tot=n;
        build(1,n,1,0),build(1,n,1,1);
        while(m--)
        {
            int op,x,l,r,w;scanf("%d%d%d",&op,&x,&l);
            if(op==1)scanf("%d",&w),adde(x,l,w);
            else if(op==2)
            {
                vec.clear();
                scanf("%d%d",&r,&w);
                query(l,r,0,1,n,1);
                for(int i=0;i<vec.size();i++)adde(x,vec[i],w);
            }
            else{
                vec.clear();
                scanf("%d%d",&r,&w);
                query(l,r,1,1,n,1);
                for(int i=0;i<vec.size();i++)adde(vec[i],x,w);
            }
        }
        dijkstra(S);
        for(int i=1;i<=n;i++)if(d[i]==1e18)printf("-1 ");else printf("%lld ",d[i]);
    }

    暂时没了。

  • 相关阅读:
    Zend Studio使用
    iOS中block实现的探究
    用python演示一个简单的AST(抽象语法树)
    Cocos2D-x权威指南: CCNode类方法:
    ListView的优化
    可变參数
    android媒体--stagefright概述【一】
    flume安装及配置
    linux包之sysstat之mpstat与pidstat命令
    Java实现第十届蓝桥杯等差数列
  • 原文地址:https://www.cnblogs.com/hfctf0210/p/11038645.html
Copyright © 2011-2022 走看看