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 }
深深地明白自己的弱小