bzoj3731: Gty的超级妹子树(树分块)

传送门

 

分块树,代码参考了Manchery的

具体细节还是看代码好了

这题卡常……注意常数写好点……

  1 //minamoto
  2 #include<iostream>
  3 #include<cstdio>
  4 #include<algorithm>
  5 #include<cmath>
  6 #include<vector>
  7 using namespace std;
  8 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
  9 char buf[1<<21],*p1=buf,*p2=buf;
 10 inline int read(){
 11     #define num ch-'0'
 12     char ch;bool flag=0;int res;
 13     while(!isdigit(ch=getc()))
 14     (ch=='-')&&(flag=true);
 15     for(res=num;isdigit(ch=getc());res=res*10+num);
 16     (flag)&&(res=-res);
 17     #undef num
 18     return res;
 19 }
 20 const int N=100005;
 21 struct Block{
 22     vector<int> a;
 23     inline void insert(int x){
 24         a.insert(lower_bound(a.begin(),a.end(),x+1),x);
 25     }
 26     inline void erase(int x){
 27         a.erase(lower_bound(a.begin(),a.end(),x));
 28     }
 29     inline void modify(int x,int y){
 30         erase(x),insert(y);
 31     }
 32     inline int query(int x){
 33         return a.end()-upper_bound(a.begin(),a.end(),x);
 34     }
 35     inline int size(){return a.size();}
 36 }Blo[N];
 37 int tot,ver[N<<2],head[N],Next[N<<2],first[N];
 38 inline void add(int u,int v){
 39     ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
 40 }
 41 inline void addb(int u,int v){
 42     ver[++tot]=v,Next[tot]=first[u],first[u]=tot;
 43 }
 44 int n,B,a[N],fa[N],belong[N],bat[N],cnt;
 45 void dfs(int u,int f){
 46     fa[u]=f;
 47     if(u==1||Blo[belong[f]].size()==B)
 48     Blo[belong[u]=++cnt].insert(a[u]),addb(belong[f],belong[u]),bat[cnt]=belong[f];
 49     else Blo[belong[u]=belong[f]].insert(a[u]);
 50     for(int i=head[u];i;i=Next[i])
 51     if(ver[i]!=f) dfs(ver[i],u);
 52 }
 53 int Y,ans=0;
 54 void block_dfs(int u){
 55     ans+=Blo[u].query(Y);
 56     for(int i=first[u];i;i=Next[i])
 57     if(bat[ver[i]]==u) block_dfs(ver[i]);
 58 }
 59 void find(int u,int f){
 60     if(a[u]>Y) ++ans;
 61     for(int i=head[u];i;i=Next[i])
 62     if(ver[i]!=f&&fa[ver[i]]==u)
 63     if(belong[ver[i]]==belong[u]) find(ver[i],u);
 64     else block_dfs(belong[ver[i]]);
 65 }
 66 int c[N],d[N];
 67 void cont(int u,int f){
 68     c[++*c]=u;
 69     for(int i=head[u];i;i=Next[i])
 70     if(ver[i]!=f&&fa[ver[i]]==u)
 71     if(belong[ver[i]]==belong[u]) cont(ver[i],u);
 72     else d[++*d]=belong[ver[i]];
 73 }
 74 int main(){
 75     int q,op,u,v,lastans=0;
 76     //freopen("testdata.in","r",stdin);
 77     n=read(),B=sqrt(n);
 78     for(int i=1;i<n;++i)
 79     u=read(),v=read(),add(u,v),add(v,u);
 80     for(int i=1;i<=n;++i) a[i]=read();
 81     dfs(1,0);q=read();
 82     while(q--){
 83         op=read();
 84         switch(op){
 85             case 0:{
 86                 u=read(),v=read();
 87                 u^=lastans,v^=lastans;
 88                 Y=v,ans=0;
 89                 find(u,fa[u]);
 90                 printf("%d\n",lastans=ans);
 91                 break;
 92             }
 93             case 1:{
 94                 u=read(),v=read();
 95                 u^=lastans,v^=lastans;
 96                 Blo[belong[u]].modify(a[u],v);
 97                 a[u]=v;
 98                 break;
 99             }
100             case 2:{
101                 u=read(),v=read();
102                 u^=lastans,v^=lastans;
103                 a[++n]=v;
104                 add(u,n),add(n,u);
105                 fa[n]=u;
106                 if(Blo[belong[u]].size()==B)
107                 Blo[belong[n]=++cnt].insert(a[n]),addb(belong[u],belong[n]),bat[cnt]=belong[u];
108                 else Blo[belong[n]=belong[u]].insert(a[n]);
109                 break;
110             }
111             case 3:{
112                 u=read(),u^=lastans;
113                 if(belong[u]!=belong[fa[u]]){
114                     fa[u]=0,bat[belong[u]]=0;break;
115                 }
116                 cont(u,fa[u]);
117                 belong[u]=++cnt;
118                 for(int i=1;i<=*c;++i){
119                     Blo[belong[fa[u]]].erase(a[c[i]]);
120                     Blo[cnt].insert(a[c[i]]);
121                     belong[c[i]]=cnt;
122                 }
123                 for(int i=1;i<=*d;++i)
124                 addb(cnt,d[i]),bat[d[i]]=cnt;
125                 fa[u]=0,*c=*d=0;
126                 break;
127             }
128         }
129     }
130     return 0;
131 }

 

posted @ 2018-09-04 21:26  bztMinamoto  阅读(324)  评论(0编辑  收藏  举报
Live2D