zoukankan      html  css  js  c++  java
  • BZOJ 3639: Query on a tree VII LCT+set维护子树信息

    用 set 维护子树信息,细节较多。

    Code:

    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <set> 
    #include <string>
    #define setIO(s) freopen(s".in","r",stdin), freopen(s".out","w",stdout)  
    #define maxn 100009
    #define inf -2147483647
    using namespace std;
    int fat[maxn];
    int n,m;
    struct Graph{
        int head[maxn],to[maxn<<1],nex[maxn<<1],cnt;    
        void addedge(int u,int v){ nex[++cnt]=head[u],head[u]=cnt,to[cnt]=v; }  
        void dfs(int u,int father){
            fat[u]=father;
            for(int v=head[u];v;v=nex[v]) if(to[v]!=father) dfs(to[v],u);
        }
        void Build(){
            for(int i=1;i<n;++i){
                int a,b;
                scanf("%d%d",&a,&b), addedge(a,b),addedge(b,a); 
            }
            dfs(1,0);
        }
    }G;
    int col[maxn],v[maxn]; 
    struct LCT{
    	multiset<int>s[maxn]; 
        multiset<int>::reverse_iterator rit;
        int ch[maxn][2],f[maxn];
        int siz[maxn],mx[maxn]; 
        void init(){ mx[0]=-2147483647; } 
        int value(int x) { rit=s[x].rbegin(); return (*rit);  }
        int get(int x){ return ch[f[x]][1]==x; }
        int lson(int x){ return ch[x][0];}
        int rson(int x){ return ch[x][1];}
        int isRoot(int x){ return !(ch[f[x]][0]==x||ch[f[x]][1]==x); }
        void pushup(int x){ 
        	if(!x) return; 
        	mx[x]=max(v[x],max(mx[lson(x)],mx[rson(x)])); 
        	if(!s[x].empty()) mx[x]=max(mx[x],value(x)); 
        }
        void rotate(int x)
        {
            int old=f[x],oldf=f[old],which=get(x);
            if(!isRoot(old)) ch[oldf][ch[oldf][1]==old]=x; 
            ch[old][which]=ch[x][which^1],f[ch[old][which]]=old;
            ch[x][which^1]=old,f[old]=x,f[x]=oldf;
            pushup(old),pushup(x);
        }
        void splay(int x)
        {
            int u=x;
            while(!isRoot(u)) u=f[u];
            u=f[u];
            for(int fa;(fa=f[x])!=u;rotate(x)) 
                if(f[fa]!=u) rotate(get(fa)==get(x)?fa:x);
        }
        void Access(int x){
            for(int y=0;x;y=x,x=f[x]){
                splay(x);
                if(rson(x)) s[x].insert(mx[rson(x)]);  
                if(ch[x][1]=y) s[x].erase(s[x].find(mx[y])) ;  
                pushup(x);
            }
        }
        void cut(int a,int b){        
            if(!a) return; 
            Access(b),splay(b),ch[b][0]=f[ch[b][0]]=0,pushup(b);
        }
        void link(int a,int b)
        {                    
            if(!a) return; 
            Access(a),splay(a),Access(b),splay(b);
            f[b]=a,ch[a][1]=b,pushup(a);
        }
        int findRoot(int a){
            Access(a),splay(a);
            while(ch[a][0]) a=ch[a][0];
            return a;
        }
    }tree[2];
    int main(){
        //setIO("debug");
        scanf("%d",&n),G.Build(),tree[0].init(),tree[1].init();
        for(int i=1;i<=n;++i) scanf("%d",&col[i]); 
        for(int i=1;i<=n;++i) scanf("%d",&v[i]); 
        fat[1]=n+1,v[n+1]=tree[1].mx[n+1]=tree[0].mx[n+1]=inf; 
        for(int i=1;i<=n;++i) tree[col[i]].link(fat[i],i);     
        int opt,a;
        scanf("%d",&m);
        for(int i=1;i<=m;++i){
            scanf("%d%d",&opt,&a);
            if(opt==0) {
                int x=tree[col[a]].findRoot(a);
                tree[col[a]].splay(x); 
                if(col[x]==col[a]) printf("%d
    ",tree[col[a]].mx[x]);
                else printf("%d
    ",tree[col[a]].mx[tree[col[a]].ch[x][1]]); 
            }
            if(opt==1) {
                tree[col[a]].cut(fat[a],a),col[a]^=1,tree[col[a]].link(fat[a],a);
            }
            if(opt==2)
            {
            	tree[col[a]].Access(a),tree[col[a]].splay(a);
                scanf("%d",&v[a]); 
            	tree[col[a]].pushup(a); 
            } 
        }
        return 0;
    }
    

      

  • 相关阅读:
    DELETE和DELETE FROM有什么区别
    [转]DBA,SYSDBA,SYSOPER三者的区别
    DML语言练习,数据增删改查,复制清空表
    Oracle数据库sys为什么只能以sysdba登录
    Oracle添加数据文件创建表空间,创建用户代码
    ORACLE建表练习
    全局唯一标识符(GUID)
    [转]Java总结篇系列:Java泛型
    Strategy模式
    Android 第三方应用广告拦截实现
  • 原文地址:https://www.cnblogs.com/guangheli/p/10159842.html
Copyright © 2011-2022 走看看