[spojQTREE7]Query on a tree VII

类似于QTREE5QTREE6组合,即将原本维护子树范围内点数改为维护子树范围内最小值即可,由于最小值没有可减性,因此需要使用set

另外关于make_root中没有rev的修改,实际上也不需要改变

时间复杂度为$o(n\log^{2}n)$,可以通过

[spojQTREE7]Query on a tree VII
  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define N 100005
  4 vector<int>v[N];
  5 int n,m,p,x,y,f[N],col[N];
  6 struct LCT{
  7     int fa[N],val[N],f[N],ch[N][2];
  8     multiset<int>S[N];
  9     bool check(int k){
 10         return ((ch[fa[k]][0]!=k)&&(ch[fa[k]][1]!=k));
 11     }
 12     int which(int k){
 13         return ch[fa[k]][1]==k;
 14     }
 15     int get(int k){
 16         if (S[k].empty())return 0;
 17         return *--S[k].end();
 18     }
 19     void up(int k){
 20         f[k]=max(max(f[ch[k][0]],f[ch[k][1]]),max(get(k),val[k]));
 21     }
 22     void add_vir(int k){
 23         S[fa[k]].insert(f[k]);
 24     }
 25     void del_vir(int k){
 26         S[fa[k]].erase(S[fa[k]].find(f[k]));
 27     }
 28     void rotate(int k){
 29         int f=fa[k],g=fa[f],p=which(k);
 30         fa[k]=g;
 31         if (!check(f))ch[g][which(f)]=k;
 32         fa[ch[k][p^1]]=f,ch[f][p]=ch[k][p^1];
 33         fa[f]=k,ch[k][p^1]=f;
 34         up(f),up(k);
 35     }
 36     void splay(int k){
 37         for(int i=fa[k];!check(k);i=fa[k]){
 38             if (!check(i)){
 39                 if (which(i)==which(k))rotate(i);
 40                 else rotate(k);
 41             }
 42             rotate(k);
 43         }
 44     }
 45     void access(int k){
 46         int lst=0;
 47         while (k){
 48             splay(k);
 49             if (ch[k][1])add_vir(ch[k][1]);
 50             if (lst)del_vir(lst);
 51             ch[k][1]=lst,up(k);
 52             lst=k,k=fa[k];
 53         }
 54     }
 55     void make_root(int k){
 56         access(k);
 57         splay(k);
 58     }
 59     int find_root(int k){
 60         access(k);
 61         splay(k);
 62         while (ch[k][0])k=ch[k][0];
 63         splay(k);
 64         return k;
 65     }
 66     void add(int x,int y){
 67         make_root(x);
 68         make_root(y);
 69         fa[y]=x,add_vir(y),up(x);
 70     }
 71     void del(int x,int y){
 72         make_root(x);
 73         access(y);
 74         fa[y]=ch[x][1]=0,up(x);
 75     }
 76     void upd_val(int k,int x){
 77         make_root(k);
 78         val[k]=x,up(k);
 79     }
 80     int query(int k){
 81         k=find_root(k);
 82         return f[ch[k][1]];
 83     }
 84 }T[2];
 85 void dfs(int k,int fa){
 86     f[k]=fa;
 87     for(int i=0;i<v[k].size();i++)
 88         if (v[k][i]!=fa)dfs(v[k][i],k);
 89 }
 90 int main(){
 91     scanf("%d",&n);
 92     for(int i=1;i<n;i++){
 93         scanf("%d%d",&x,&y);
 94         v[x].push_back(y);
 95         v[y].push_back(x);
 96     }
 97     dfs(1,n+1);
 98     for(int i=1;i<=n;i++){
 99         scanf("%d",&col[i]);
100         T[col[i]].add(f[i],i);
101     }
102     for(int i=1;i<=n;i++){
103         scanf("%d",&x);
104         T[0].upd_val(i,x),T[1].upd_val(i,x);
105     }
106     scanf("%d",&m);
107     for(int i=1;i<=m;i++){
108         scanf("%d%d",&p,&x);
109         if (!p)printf("%d\n",T[col[x]].query(x));
110         if (p==1){
111             T[col[x]].del(f[x],x);
112             col[x]^=1;
113             T[col[x]].add(f[x],x);
114         }
115         if (p==2){
116             scanf("%d",&y);
117             T[col[x]].upd_val(x,y);
118         }
119     }
120     return 0;
121 }
View Code

 

上一篇:201621123040 《Java程序设计》第1周学习总结


下一篇:019 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 13 数据类型转换的代码示例