[spojQTREE7]Query on a tree VII

QTREE5QTREE6组合,即将原本维护子树范围内点数改为维护子树范围内最小值即可,由于最小值没有可减性,因此需要使用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 }
View Code
原文地址:https://www.cnblogs.com/PYWBKTDA/p/15337596.html