bzoj Gty的超级妹子树 块状树

Gty的超级妹子树

Time Limit: 7 Sec  Memory Limit: 32 MB
Submit: 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

2
1 2
10 20
1
0 1 5

Sample Output

2

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 }

 

posted @ 2018-03-31 07:37  Kaiser-  阅读(304)  评论(0编辑  收藏  举报