类似于QTREE5和QTREE6组合,即将原本维护子树范围内点数改为维护子树范围内最小值即可,由于最小值没有可减性,因此需要使用set
另外关于make_root中没有rev的修改,实际上也不需要改变
时间复杂度为$o(n\log^{2}n)$,可以通过
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