即QTREE5和QTREE6组合,即将原本维护子树范围内点数改为维护子树范围内最小值即可,由于最小值没有可减性,因此需要使用set
(虽然形式上与QTREE5类似,但QTREE5维护的信息更巧妙一些,而这题比较直接)
另外关于make_root中没有rev的修改,实际上也不需要改变
时间复杂度为$o(nlog^{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 LCT(){ 10 memset(val,-0x3f,sizeof(val)); 11 memset(f,-0x3f,sizeof(f)); 12 } 13 bool check(int k){ 14 return ((ch[fa[k]][0]!=k)&&(ch[fa[k]][1]!=k)); 15 } 16 int which(int k){ 17 return ch[fa[k]][1]==k; 18 } 19 int get(int k){ 20 if (S[k].empty())return -1e9; 21 return *--S[k].end(); 22 } 23 void up(int k){ 24 f[k]=max(max(f[ch[k][0]],f[ch[k][1]]),max(get(k),val[k])); 25 } 26 void add_vir(int k){ 27 S[fa[k]].insert(f[k]); 28 } 29 void del_vir(int k){ 30 S[fa[k]].erase(S[fa[k]].find(f[k])); 31 } 32 void rotate(int k){ 33 int f=fa[k],g=fa[f],p=which(k); 34 fa[k]=g; 35 if (!check(f))ch[g][which(f)]=k; 36 fa[ch[k][p^1]]=f,ch[f][p]=ch[k][p^1]; 37 fa[f]=k,ch[k][p^1]=f; 38 up(f),up(k); 39 } 40 void splay(int k){ 41 for(int i=fa[k];!check(k);i=fa[k]){ 42 if (!check(i)){ 43 if (which(i)==which(k))rotate(i); 44 else rotate(k); 45 } 46 rotate(k); 47 } 48 } 49 void access(int k){ 50 int lst=0; 51 while (k){ 52 splay(k); 53 if (ch[k][1])add_vir(ch[k][1]); 54 if (lst)del_vir(lst); 55 ch[k][1]=lst,up(k); 56 lst=k,k=fa[k]; 57 } 58 } 59 void make_root(int k){ 60 access(k); 61 splay(k); 62 } 63 int find_root(int k){ 64 access(k); 65 splay(k); 66 while (ch[k][0])k=ch[k][0]; 67 splay(k); 68 return k; 69 } 70 void add(int x,int y){ 71 make_root(x); 72 make_root(y); 73 fa[y]=x,add_vir(y),up(x); 74 } 75 void del(int x,int y){ 76 make_root(x); 77 access(y); 78 fa[y]=ch[x][1]=0,up(x); 79 } 80 void upd_val(int k,int x){ 81 make_root(k); 82 val[k]=x,up(k); 83 } 84 int query(int k){ 85 k=find_root(k); 86 return f[ch[k][1]]; 87 } 88 }T[2]; 89 void dfs(int k,int fa){ 90 f[k]=fa; 91 for(int i=0;i<v[k].size();i++) 92 if (v[k][i]!=fa)dfs(v[k][i],k); 93 } 94 int main(){ 95 scanf("%d",&n); 96 for(int i=1;i<n;i++){ 97 scanf("%d%d",&x,&y); 98 v[x].push_back(y); 99 v[y].push_back(x); 100 } 101 dfs(1,n+1); 102 for(int i=1;i<=n;i++){ 103 scanf("%d",&col[i]); 104 T[col[i]].add(f[i],i); 105 } 106 for(int i=1;i<=n;i++){ 107 scanf("%d",&x); 108 T[0].upd_val(i,x),T[1].upd_val(i,x); 109 } 110 scanf("%d",&m); 111 for(int i=1;i<=m;i++){ 112 scanf("%d%d",&p,&x); 113 if (!p)printf("%d ",T[col[x]].query(x)); 114 if (p==1){ 115 T[col[x]].del(f[x],x); 116 col[x]^=1; 117 T[col[x]].add(f[x],x); 118 } 119 if (p==2){ 120 scanf("%d",&y); 121 T[0].upd_val(x,y); 122 T[1].upd_val(x,y); 123 } 124 } 125 return 0; 126 }