Gty的超级妹子树
Time Limit: 7 Sec Memory Limit: 32 MBSubmit: 500 Solved: 122
[Submit][Status][Discuss]
Description
我曾在青山之中遇过你,
新竹做杖,鬓插紫茱萸。
跣足踏过无边丝雨,
又拾起燕川雪片片落如席……
Gty神(xian)犇(chong)从来不缺妹子……
他又来到了一棵妹子树下,发现每个妹子有一个美丽度……
由于Gty很 哲♂学 也很 机♂智,他只对美丽度大于某个值的妹子感兴趣。
他想知道某个子树中美丽度大于x的妹子个数。
某个妹子的美丽度可能发生变化……
树上可能会出现一只新的妹子……
但是……树枝可能会断裂,于是,Gty惊讶地发现,他的面前变成了一片妹子树组成的森林……
维护一棵初始有n个节点的有根树(根节点为1),树上节点编号为1-n,每个点有一个权值wi。它可能会变成森林。
支持以下操作:
0 u x 询问以u为根的子树中,严格大于x的值的个数。(u^=lastans,x^=lastans)
1 u x 把u节点的权值改成x。(u^=lastans,x^=lastans)
2 u x 添加一个编号为"当前树中节点数+1"的节点,其父节点为u,其权值为x。(u^=lastans,x^=lastans)
3 u 删除节点u与其父节点之间的路径。此时u的父节点变成叶子节点,u变成分裂出的树的根。(u^=lastans)
最开始时lastans=0。
Input
输入第一行包括一个正整数n(1<=n<=100000),代表树上的初始节点数。
接下来n-1行,每行2个整数u,v,为树上的一条无向边。
任何时刻,树上的任何权值大于等于0,且两两不同。
接下来1行,包括n个整数wi,表示初始时每个节点的权值。
接下来1行,包括1个整数m(1<=m<=100000),表示操作总数。
接下来m行,每行最开始包括一个整数op,
若op=3,该行还会有一个整数u;
若op不等于3,该行还会有两个整数u,x;
op,u,x的范围见题目描述。
保证题目涉及的所有数在int内。
Output
对每个op=0,输出一行,包括一个整数,意义见题目描述。
Sample Input
1 2
10 20
1
0 1 5
Sample Output
HINT
数据范围见描述。
Source
题解:分块的方式真的不行,被菊花图卡的飞起,这里加了一个删除操作,就是将一个块分成两个,如果刚好一个块的话就直接分出,其实
貌似改的地方不多。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <cstdlib> 6 #include <algorithm> 7 #include <vector> 8 #define N 200006 9 #define M 400006 10 11 using namespace std; 12 inline int read(){ 13 int ret=0;char ch=getchar(); 14 while (ch<'0'||ch>'9') ch=getchar(); 15 while ('0'<=ch&&ch<='9'){ 16 ret=ret*10-48+ch; 17 ch=getchar(); 18 } 19 return ret; 20 } 21 22 const int KK=400; 23 vector<int> seq[N]; 24 25 struct edge{ 26 int adj,next; 27 edge(){} 28 edge(int _adj,int _next):adj(_adj),next(_next){} 29 } e[M]; 30 int n,g[N],m; 31 void AddEdge(int u,int v){ 32 e[++m]=edge(v,g[u]);g[u]=m; 33 e[++m]=edge(u,g[v]);g[v]=m; 34 } 35 int w[N]; 36 37 vector<int> nxt[N]; 38 int fa[N],bl[N],sz[N],cnt,top[N]; 39 void refresh(int u,int p){ 40 for (;p>0&&seq[u][p]<seq[u][p-1];--p)swap(seq[u][p],seq[u][p-1]); 41 for (;p<sz[u]-1&&seq[u][p]>seq[u][p+1];++p)swap(seq[u][p],seq[u][p+1]); 42 } 43 void newnode(int u){ 44 if (sz[bl[fa[u]]]==KK){ 45 sz[bl[u]=++cnt]=0; 46 top[cnt]=u; 47 } 48 else bl[u]=bl[fa[u]]; 49 ++sz[bl[u]]; 50 } 51 void dfs(int u){ 52 newnode(u); 53 for (int i=g[u];i;i=e[i].next){ 54 int v=e[i].adj; 55 if (v==fa[u]) continue; 56 fa[v]=u; 57 dfs(v); 58 } 59 } 60 void dfs_pre(int u){ 61 seq[bl[u]].push_back(w[u]);++sz[bl[u]]; 62 for (int i=g[u];i;i=e[i].next)if (fa[e[i].adj]==u){ 63 int v=e[i].adj; 64 if (bl[v]==bl[u]) dfs_pre(v); 65 else nxt[bl[u]].push_back(bl[v]); 66 } 67 } 68 void prepare(int id){ 69 seq[id].clear();vector<int>(seq[id]).swap(seq[id]); 70 nxt[id].clear();vector<int>(nxt[id]).swap(nxt[id]); 71 sz[id]=0; 72 dfs_pre(top[id]); 73 sort(seq[id].begin(),seq[id].end()); 74 } 75 76 int solve(int u,int lmt){ 77 int l=-1,r=sz[u],mid; 78 while (l+1<r){ 79 mid=l+r>>1; 80 if (seq[u][mid]<=lmt) l=mid; 81 else r=mid; 82 } 83 int ret=sz[u]-l-1; 84 for (int j=nxt[u].size()-1;j>=0;--j) ret+=solve(nxt[u][j],lmt); 85 return ret; 86 } 87 int query(int u,int lmt){ 88 if (bl[u]!=bl[fa[u]]) return solve(bl[u],lmt); 89 int ret=w[u]>lmt; 90 for (int i=g[u];i;i=e[i].next)if (fa[e[i].adj]==u)ret+=query(e[i].adj,lmt); 91 return ret; 92 } 93 94 void modify(int u,int x){ 95 int p; 96 for (int i=0;i<sz[bl[u]];++i) 97 if (seq[bl[u]][i]==w[u]){p=i;break;} 98 w[u]=x;seq[bl[u]][p]=x; 99 refresh(bl[u],p); 100 } 101 102 void create(int u,int x){ 103 AddEdge(u,++n);fa[n]=u;w[n]=x; 104 int tmp=cnt; 105 newnode(n); 106 seq[bl[n]].push_back(w[n]); 107 refresh(bl[n],sz[bl[n]]-1); 108 if (tmp<cnt) nxt[bl[u]].push_back(cnt); 109 } 110 111 void dfs_update(int u,int last,int now){ 112 bl[u]=now; 113 for (int i=g[u];i;i=e[i].next)if (fa[e[i].adj]==u) 114 if (bl[e[i].adj]==last) dfs_update(e[i].adj,last,now); 115 } 116 117 void cut(int u){ 118 int lst=bl[u]; 119 if (bl[fa[u]]!=bl[u]){ 120 int f=bl[fa[u]]; 121 for (vector<int>::iterator it=nxt[f].begin();it!=nxt[f].end();++it) 122 if ((*it)==lst){nxt[f].erase(it);break;} 123 fa[u]=0;return; 124 } 125 top[++cnt]=u; 126 fa[u]=0; 127 dfs_update(u,lst,cnt); 128 prepare(lst); 129 prepare(cnt); 130 } 131 132 int main(){ 133 n=read(); 134 memset(g,0,sizeof(g));m=1; 135 for (int i=1;i<n;++i) AddEdge(read(),read()); 136 for (int i=1;i<=n;++i) w[i]=read(); 137 fa[1]=0;bl[0]=0;sz[0]=KK;cnt=0; 138 dfs(1); 139 int lastans=0; 140 for (int i=1;i<=cnt;++i) prepare(i); 141 for (int Q=read();Q;Q--){ 142 int op=read(),u=read()^lastans,x; 143 if (op<3) x=read()^lastans; 144 else cut(u); 145 if (op==0) printf("%d\n",lastans=query(u,x)); 146 else if (op==1) modify(u,x); 147 else if (op==2) create(u,x); 148 } 149 }