bzoj 3720 Gty的妹子樹 樹分塊?瞎搞
阿新 • • 發佈:2018-03-27
mit clu set memset names 但是 ios 等於 getc
Submit: 2149 Solved: 781
[Submit][Status][Discuss]
某個妹子的美麗度可能發生變化……
樹上可能會出現一只新的妹子……
維護一棵初始有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)
最開始時lastans=0。
1 2
10 20
1
0 1 5
Gty的妹子樹
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2149 Solved: 781
[Submit][Status][Discuss]
Description
我曾在弦歌之中聽過你,
檀板聲碎,半出折子戲。
舞榭歌臺被風吹去,
歲月深處尚有余音一縷……
Gty神(xian)犇(chong)從來不缺妹子……
他來到了一棵妹子樹下,發現每個妹子有一個美麗度……
由於Gty很哲♂學,他只對美麗度大於某個值的妹子感興趣。
他想知道某個子樹中美麗度大於k的妹子個數。
某個妹子的美麗度可能發生變化……
樹上可能會出現一只新的妹子……
維護一棵初始有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)
最開始時lastans=0。
Input
輸入第一行包括一個正整數n(1<=n<=30000),代表樹上的初始節點數。
接下來n-1行,每行2個整數u,v,為樹上的一條無向邊。
任何時刻,樹上的任何權值大於等於0,且兩兩不同。
接下來1行,包括n個整數wi,表示初始時每個節點的權值。
接下來1行,包括1個整數m(1<=m<=30000),表示操作總數。
接下來m行,每行包括三個整數 op,u,v:
op,u,v的含義見題目描述。
保證題目涉及的所有數在int內。
Output
對每個op=0,輸出一行,包括一個整數,意義見題目描述。
Sample Input
21 2
10 20
1
Sample Output
2HINT
2017.9.28新加數據一組by GXZlegend,未重測
Source
傳說中的樹分塊,但是會被暴力卡,我貌似沒找出什麽方法,
和根一起一起到達根號n就就分塊,這個沒什麽用,會被菊花圖卡掉的。
1 #include<cstring> 2 #include<cstdio> 3 #include<iostream> 4 #include<algorithm> 5 #include<cmath> 6 7 #define N 60007 8 using namespace std; 9 inline int read() 10 { 11 int x=0,f=1;char ch=getchar(); 12 while(!isdigit(ch)){if(ch==‘-‘)f=-1;ch=getchar();} 13 while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-‘0‘;ch=getchar();} 14 return x*f; 15 } 16 17 int n,m,block,ans,tot; 18 int a[N],fa[N],bl[N]; 19 int cnt,hed[N],nxt[N<<1],rea[N<<1]; 20 int Cnt,Hed[N],Nxt[N<<1],Rea[N<<1]; 21 22 struct Node 23 { 24 int a[207],siz; 25 void insert(int x){a[++siz]=x;} 26 void change(int x,int y) 27 { 28 int t=upper_bound(a+1,a+siz+1,x)-a;t--; 29 a[t]=y; 30 sort(a+1,a+siz+1); 31 } 32 int query(int x) 33 { 34 int t=upper_bound(a+1,a+siz+1,x)-a; 35 return siz-t+1; 36 } 37 }blo[N]; 38 inline void add(int u,int v) 39 { 40 nxt[++cnt]=hed[u]; 41 hed[u]=cnt; 42 rea[cnt]=v; 43 } 44 inline void add_two_way(int u,int v) 45 { 46 add(u,v); 47 add(v,u); 48 } 49 inline void ins(int u,int v) 50 { 51 Nxt[++Cnt]=Hed[u]; 52 Hed[u]=Cnt; 53 Rea[Cnt]=v; 54 } 55 void dfs(int u) 56 { 57 if (blo[bl[fa[u]]].siz==block) 58 blo[bl[u]=++tot].insert(a[u]),ins(bl[fa[u]],tot); 59 else blo[bl[u]=bl[fa[u]]].insert(a[u]); 60 for (int i=hed[u];i!=-1;i=nxt[i]) 61 { 62 int v=rea[i]; 63 if (v==fa[u]) continue; 64 fa[v]=u,dfs(v); 65 } 66 } 67 void block_dfs(int u,int z) 68 { 69 ans+=blo[u].query(z); 70 for (int i=Hed[u];i!=-1;i=Nxt[i]) 71 { 72 int v=Rea[i]; 73 block_dfs(v,z); 74 } 75 } 76 void solve(int u,int z) 77 { 78 if (a[u]>z) ans++; 79 for (int i=hed[u];i!=-1;i=nxt[i]) 80 { 81 int v=rea[i]; 82 if (v==fa[u]) continue; 83 if (bl[v]==bl[u]) solve(v,z); 84 else block_dfs(bl[v],z); 85 } 86 } 87 int main() 88 { 89 memset(hed,-1,sizeof(hed)); 90 memset(Hed,-1,sizeof(Hed)); 91 n=read(),block=sqrt(n); 92 for (int i=1;i<n;i++) 93 add_two_way(read(),read()); 94 for (int i=1;i<=n;i++) a[i]=read(); 95 dfs(1); 96 for (int i=1;i<=tot;i++) 97 sort(blo[i].a+1,blo[i].a+blo[i].siz+1); 98 99 m=read(); 100 for (int i=1;i<=m;i++) 101 { 102 int opt=read(),x=read(),y=read(); 103 x^=ans,y^=ans; 104 if (opt==0) 105 { 106 ans=0; 107 solve(x,y); 108 printf("%d\n",ans); 109 } 110 else if (opt==1) 111 { 112 blo[bl[x]].change(a[x],y); 113 a[x]=y; 114 } 115 else 116 { 117 a[++n]=y,add_two_way(x,n),fa[n]=x; 118 if (blo[bl[x]].siz==block) 119 blo[bl[n]=++tot].insert(y),ins(bl[x],tot); 120 else 121 { 122 blo[bl[n]=bl[x]].insert(y); 123 sort(blo[bl[n]].a+1,blo[bl[n]].a+blo[bl[n]].siz+1); 124 } 125 } 126 } 127 }
bzoj 3720 Gty的妹子樹 樹分塊?瞎搞