• 主席树+启发式合并(LT) BZOJ3123


    好久没做题了,写道SBT又RE又T

    查询:主席树裸题。

    修改:对于两个树合并重建小的树。

    注意fa[x][i]重新计算时要清空

    #include<cstdio> 
    #include<cctype> 
    #include<cstring> 
    #include<algorithm> 
    using namespace std; 
    inline int read() 
    { 
        char c=getchar();int x=0,sig=1; 
        for(;!isdigit(c);c=getchar()) if(c=='-') sig=-1; 
        for(;isdigit(c);c=getchar()) x=x*10+c-'0'; 
        return x*sig; 
    } 
    inline void print(int x) 
    { 
        int buf[10],l=0; 
        if(!x) l++; 
        while(x) buf[++l]=x%10,x/=10; 
        for(;l;l--) putchar(buf[l]+'0'); 
        putchar('
    '); 
    } 
    const int maxn=80010; 
    const int maxnode=10000010; 
    int ls[maxnode],rs[maxnode],s[maxnode],ToT; 
    void update(int& y,int x,int l,int r,int pos) 
    { 
         s[y=++ToT]=s[x]+1;if(l==r) return; 
         int mid=l+r>>1;ls[y]=ls[x];rs[y]=rs[x]; 
         if(pos<=mid) update(ls[y],ls[x],l,mid,pos); 
         else update(rs[y],rs[x],mid+1,r,pos); 
    } 
    int query(int x1,int x2,int y1,int y2,int l,int r,int k) 
    { 
        if(l==r) return l; 
        int mid=l+r>>1,k2=s[ls[y1]]+s[ls[y2]]-s[ls[x1]]-s[ls[x2]]; 
        if(k<=k2) return query(ls[x1],ls[x2],ls[y1],ls[y2],l,mid,k); 
        return query(rs[x1],rs[x2],rs[y1],rs[y2],mid+1,r,k-k2); 
    } 
    int n,m,q,val[maxn],tmp[maxn],root[maxn],lastans; 
    int first[maxn],next[maxn*2],to[maxn*2],e,fa[maxn][20],dep[maxn]; 
    int pa[maxn],sz[maxn];
    void AddEdge(int a,int b) 
    { 
        to[++e]=b;next[e]=first[a];first[a]=e; 
        to[++e]=a;next[e]=first[b];first[b]=e; 
    } 
    void dfs(int x,int f) 
    { 
        dep[x]=dep[fa[x][0]=f]+1;update(root[x],root[f],1,n,val[x]);
        sz[pa[x]]++;
        for(int i=1;i<17;i++) fa[x][i]=fa[fa[x][i-1]][i-1]; 
        for(int i=first[x];i;i=next[i]) if(to[i]!=f) pa[to[i]]=pa[x],dfs(to[i],x); 
    } 
    int lca(int p,int q) 
    { 
        if(dep[p]<dep[q]) swap(p,q);
        for(int i=19;i>=0;i--) if((1<<i)<=dep[p]-dep[q]) p=fa[p][i];
        for(int i=19;i>=0;i--) if(fa[p][i]!=fa[q][i]) p=fa[p][i],q=fa[q][i];
        return p==q?p:fa[p][0];
    }
    int main() 
    { 
        read();n=read();m=read();q=read(); 
        for(int i=1;i<=n;i++) tmp[i]=val[i]=read();
        sort(tmp+1,tmp+n+1); 
        for(int i=1;i<=n;i++) val[i]=lower_bound(tmp+1,tmp+n+1,val[i])-tmp; 
        for(int i=0;i<m;i++) AddEdge(read(),read());
        for(int i=1;i<=n;i++) if(!fa[i][0]) pa[i]=i,dfs(i,0); 
        for(int i=0;i<q;i++) 
        { 
            char tp=getchar(); 
            while(!isalpha(tp)) tp=getchar(); 
            if(tp=='Q') 
            { 
                int x=read()^lastans,y=read()^lastans,k=read()^lastans; 
                int c=lca(x,y); 
                print(lastans=tmp[query(root[c],root[fa[c][0]],root[x],root[y],1,n,k)]); 
            }
            else
            { 
                int u=read()^lastans,v=read()^lastans; 
                int x=pa[u],y=pa[v]; 
                if(sz[x]>sz[y]) swap(x,y),swap(u,v); 
                pa[u]=y;AddEdge(u,v);dfs(u,v); 
            } 
        } 
        return 0; 
    }
    View Code
  • 相关阅读:
    java读取properties 属性文件
    oracle中插入一条数据,id自动增长,插入之后怎么得到这个id(sequence的使用)
    Android布局实现圆角边框
    TabHost中使用startActivityForResult无法接收返回值的解决方案[转]
    ORA00937: not a singlegroup group function
    MVC与WebForm最大的区别
    使用SQL Server存储ASP.NET Session变量
    JS中的event 对象详解
    一列多行值合并成一个值(MS SQL SERVER 2008)
    c#如何共享程序集
  • 原文地址:https://www.cnblogs.com/wzj-is-a-juruo/p/4506292.html
Copyright © 2020-2023  润新知