1. 程式人生 > >bzoj 3720 Gty的妹子樹

bzoj 3720 Gty的妹子樹

如果 closed bit b- lse getchar 變化 一行 ons

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

2
1 2
10 20
1
0 1 5

Sample Output

2

HINT

2017.9.28新加數據一組by GXZlegend,未重測

思路: 吐槽一下題目的數據範圍有誤,n好像要比30000大。

這題可以按照size的大小分塊,如果父親所在的塊的點的數量小於sz,那麽就把當前節點加到父親所在的塊裏面。

這樣分塊的方法可以保證塊的大小和直徑,但是不能保證塊的數量。(感覺要被卡,逃 。。。)

塊裏面用普通的一維數組記錄每個不同的權值,插入和修改的時候用暴力的插入排序維護。

時間復雜度$O(n*\sqrt{n}*\log n)$,時間復雜度比較高,但是可以卡過。

本題最好的方法是用替罪羊樹套treap來寫。

技術分享圖片
  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define rep(i,a,b) for(int i=a;i<=b;i++)
  4 #define Rep(i,a,b) for(int i=a;i>=b;i--)
  5 #define ms(i,a)    memset(a,i,sizeof(a))
  6 int const N = 100000 + 3;
  7 template<class T>void read(T &x) {
  8     x = 0;
  9     char c = 0;
 10     while(!isdigit((c))) c = getchar();
 11     while(isdigit(c)) x = x * 10 + (c ^ 48), c = getchar();
 12 }
 13 struct edge {
 14     int to, nt;
 15 } e[N << 2];
 16 struct block {
 17     int a[300], num;
 18     void ins(int x) {
 19         num++;
 20         int j = num - 1;
 21         while(j && a[j] > x) a[j + 1] = a[j], j--;
 22         a[j + 1] = x;
 23     }
 24     void modify(int x, int y) {
 25         int t = lower_bound(a + 1, a + num + 1, x) - a;
 26         rep(i, t + 1, num) a[i - 1] = a[i];
 27         num--;
 28         ins(y);
 29     }
 30     int query(int x) {
 31         return num - (upper_bound(a + 1, a + num + 1, x) - a) + 1;
 32     }
 33 } b[10000];
 34 int h[N], cnt, H[N], bl[N], n, m, a[N], sz, sum, ans,f[N];
 35 void add(int a, int b) {
 36     e[++cnt].to = b;
 37     e[cnt].nt = h[a];
 38     h[a] = cnt;
 39 }
 40 void Add(int a, int b) {
 41     e[++cnt].to = b;
 42     e[cnt].nt = H[a];
 43     H[a] = cnt;
 44 }
 45 void dfs(int x) {
 46     if(b[bl[f[x]]].num >= sz) {
 47         bl[x] = ++sum;
 48         b[sum].ins(a[x]);
 49         Add(bl[f[x]], sum);
 50     } else {
 51         bl[x] = sum;
 52         b[sum].ins(a[x]);
 53     }
 54     for(int i = h[x]; i; i = e[i].nt) {
 55         int v = e[i].to;
 56         if(v == f[x]) continue;
 57         f[v]=x;
 58         dfs(v);
 59     }
 60 }
 61 void getblock(int x, int y) {
 62     ans += b[x].query(y);
 63     for(int i = H[x]; i; i = e[i].nt) {
 64         int v = e[i].to;
 65         getblock(v, y);
 66     }
 67 }
 68 void getans(int x, int y) {
 69     if(a[x] > y) ans++;
 70     for(int i = h[x]; i; i = e[i].nt) {
 71         int v = e[i].to;
 72         if(v == f[x]) continue;
 73         if(bl[v] == bl[x]) getans(v, y);
 74         else getblock(bl[v], y);
 75     }
 76 }
 77 int main() {
 78     read(n);
 79     sz = sqrt(n);
 80     rep(i, 1, n - 1) {
 81         int x, y;
 82         read(x);
 83         read(y);
 84         add(x, y);
 85         add(y, x);
 86     }
 87     rep(i, 1, n) read(a[i]);
 88     dfs(1);
 89     read(m);
 90     while(m--) {
 91         int k, x, y;
 92         read(k);
 93         read(x);
 94         read(y);
 95         x ^= ans;
 96         y ^= ans;
 97         if(k == 0) {
 98             ans = 0;
 99             getans(x,y);
100             printf("%d\n", ans);
101         }
102         if(k == 1) {
103             b[bl[x]].modify(a[x], y);
104             a[x] = y;
105         }
106         if(k == 2) {
107             a[++n] = y;
108             f[n]=x;
109             add(x, n);
110             if(b[bl[x]].num >= sz) {
111                 bl[n] = ++sum;
112                 b[sum].ins(y);
113                 Add(bl[x], sum);
114             } else {
115                 bl[n] = bl[x];
116                 b[bl[n]].ins(y);
117             }
118         }
119     }
120     return 0;
121 }
View Code

bzoj 3720 Gty的妹子樹