bzoj3720 Gty的妹子树
树分块,每个点如果其父亲的块还未满,则并入,否则自己新建一个块,询问时完整包含于一个子树的块二分,不完整包含的块直接暴力找。
代码
1 #include<cstdio> 2 #include<algorithm> 3 #include<vector> 4 #define fi first 5 #define sc second 6 #define mp make_pair 7 #define pb push_back 8 #define lb(x) (x&-x) 9 using namespace std; 10 const int N = 1000010; 11 const int inf=(1<<30)-1+(1<<30); 12 typedef long long ll; 13 typedef pair<int,int> P; 14 int dp,pre[N],p[N],tt[N],w[N],f[N],id[N],B,tot,ans; 15 int n,m,i,a,b,j; 16 vector<P> vec[N]; 17 vector<int> edge[N]; 18 void link(int x,int y) 19 { 20 dp++;pre[dp]=p[x];p[x]=dp;tt[dp]=y; 21 } 22 void dfs(int x,int fa) 23 { 24 int i=p[x]; 25 f[x]=fa; 26 while (i) 27 { 28 if (tt[i]!=fa) 29 { 30 if (vec[id[x]].size()<B) 31 { 32 id[tt[i]]=id[x]; 33 vec[id[tt[i]]].pb(mp(w[tt[i]],tt[i])); 34 } 35 else 36 { 37 id[tt[i]]=++tot; 38 vec[id[tt[i]]].pb(mp(w[tt[i]],tt[i])); 39 edge[id[x]].pb(id[tt[i]]); 40 } 41 dfs(tt[i],x); 42 } 43 i=pre[i]; 44 } 45 } 46 void sgao(int x,int v) 47 { 48 int m,l,r,i; 49 l=0;r=vec[x].size()-1; 50 while (l<=r) 51 { 52 m=(l+r)>>1; 53 if (vec[x][m].fi<=v) l=m+1;else r=m-1; 54 } 55 ans+=vec[x].size()-l; 56 for (i=0;i<edge[x].size();i++) 57 sgao(edge[x][i],v); 58 } 59 void gao(int x,int fa,int v) 60 { 61 if (w[x]>v) ans++; 62 int i=p[x]; 63 while (i) 64 { 65 if (tt[i]!=fa) 66 { 67 if (id[tt[i]]==id[x]) 68 gao(tt[i],x,v); 69 else 70 sgao(id[tt[i]],v); 71 } 72 i=pre[i]; 73 } 74 } 75 int main() 76 { 77 scanf("%d",&n); 78 B=400; 79 for (i=1;i<n;i++) 80 { 81 scanf("%d%d",&a,&b); 82 link(a,b);link(b,a); 83 } 84 for (i=1;i<=n;i++) 85 scanf("%d",&w[i]); 86 vec[id[1]].pb(mp(w[1],1)); 87 dfs(1,0); 88 for (i=0;i<=tot;i++) 89 sort(vec[i].begin(),vec[i].end()); 90 scanf("%d",&m); 91 for (i=1;i<=m;i++) 92 { 93 int typ; 94 scanf("%d%d%d",&typ,&a,&b); 95 a^=ans;b^=ans; 96 if (typ==0) 97 { 98 ans=0; 99 gao(a,f[a],b); 100 printf("%d\n",ans); 101 } 102 else 103 if (typ==1) 104 { 105 w[a]=b; 106 for (j=0;j<vec[id[a]].size();j++) 107 if (vec[id[a]][j].sc==a) vec[id[a]][j].fi=b; 108 sort(vec[id[a]].begin(),vec[id[a]].end()); 109 } 110 else 111 { 112 n++;f[n]=a;w[n]=b; 113 link(a,n); 114 if (vec[id[a]].size()<B) 115 id[n]=id[a]; 116 else 117 { 118 id[n]=++tot; 119 edge[id[a]].pb(id[n]); 120 } 121 vec[id[n]].pb(mp(w[n],n)); 122 sort(vec[id[n]].begin(),vec[id[n]].end()); 123 } 124 } 125 }