BZOJ 1036 树的统计 树链剖分or link-cut-tree

    崩溃,从上个星期开始BZOJ就一直RE,死命RE,写什么都能RE,心好累。还好吧!算了,不管它。幸亏有师兄,把那个测试数据给我测了一下,否则我都快抑郁了。加油吧!

    这道题就是一个模版题了,不过也学了点东西,比如写线段树时,数组要开到4倍。

    接下来没办法了,只能是我RE的代码了。(如果有大神知道哪里RE了,麻烦告知一声)。

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<vector>
  4 #define rep(i,j,k) for(int i = j; i <= k; i++)
  5 #define maxn 300500
  6 #define INF 0x7fffffff
  7 using namespace std;
  8   
  9 int n, key[maxn] = {0};
 10 vector<int> q[maxn];
 11   
 12 int pa[maxn] = {0}, son[maxn] = {0}, size[maxn] = {0}, top[maxn] = {0};
 13 int dep[maxn] = {0}, w[maxn] = {0}, tot = 0, maxl = -INF;
 14   
 15 void dfs(int now)
 16 {
 17     son[now] = 0;
 18     size[now] = 1;
 19     int s = q[now].size();
 20     rep(i,0,s-1)
 21     {
 22         int to = q[now][i];
 23         if( to == pa[now] ) continue;
 24         pa[to] = now;
 25         dep[to] = dep[now] + 1;
 26         dfs(to);
 27         size[now] += size[to];
 28         if( size[to] > size[son[now]] ) son[now] = to;
 29     }
 30 }
 31   
 32 void dfs2(int now,int ph)
 33 {
 34     top[now] = ph;
 35     w[now] = ++tot;
 36     if( son[now] ) dfs2(son[now],ph);
 37     int s = q[now].size();
 38     rep(i,0,s-1)
 39     {
 40         int y = q[now][i];
 41         if( y != son[now] && y != pa[now] ) dfs2(y,y);
 42     }
 43 }
 44   
 45 struct node{
 46 int l, r, maxl, sum;
 47 node(){
 48     l = r = maxl = sum = 0;
 49 }
 50 };
 51 node nod[maxn*4];
 52   
 53 void yuchu(int l,int r,int num)
 54 {
 55     nod[num].l = l, nod[num].r = r;
 56     if( l == r ){
 57         nod[num].maxl = nod[num].sum = key[l];
 58         return;
 59     }
 60     int mid = (l+r) / 2;
 61     yuchu(l,mid,num*2);
 62     yuchu(mid+1,r,num*2+1);
 63     nod[num].maxl = max(nod[num*2].maxl,nod[num*2+1].maxl);
 64     nod[num].sum = nod[num*2].sum + nod[num*2+1].sum;
 65 }
 66   
 67 void update(int po,int key,int num)
 68 {
 69     int l = nod[num].l, r = nod[num].r;
 70     if( l == r ){
 71         nod[num].sum = nod[num].maxl = key;
 72         return;
 73     }
 74     int mid = (l+r) / 2;
 75     if( po <= mid ){
 76         update(po,key,num*2);
 77     }
 78     else {
 79         update(po,key,num*2+1);
 80     }
 81     nod[num].maxl = max(nod[num*2].maxl,nod[num*2+1].maxl);
 82     nod[num].sum = nod[num*2].sum + nod[num*2+1].sum;
 83 }
 84   
 85 int qure(int ll,int rr,int num)
 86 {
 87     int l = nod[num].l, r = nod[num].r;
 88     if( l>=ll && rr >= r ){
 89         if( nod[num].maxl > maxl ) maxl = nod[num].maxl;
 90         return nod[num].sum;
 91     }
 92     int mid = (l+r) / 2;
 93     if( rr <= mid ){
 94         return qure(ll,rr,num*2);
 95     }
 96     else if( ll > mid ){
 97         return qure(ll,rr,num*2+1);
 98     }
 99     else if( ll <= mid && rr > mid ){
100         return qure(ll,mid,num*2) + qure(mid+1,rr,num*2+1);
101     }
102 }
103   
104 int quire(int x,int y,int pan)
105 {
106     int ans = 0;
107     maxl = -INF;
108     while( top[x] != top[y] ){
109         if( dep[top[x]] < dep[top[y]] ){
110             swap(x,y);
111         }
112         ans += qure(w[top[x]],w[x],1);
113         x = pa[top[x]];
114     }
115     if( dep[x] > dep[y] ) swap(x,y);
116     ans += qure(w[x],w[y],1);
117     if( pan ) return maxl;
118     else return ans; 
119 }
120   
121 int main()
122 {
123     scanf("%d", &n);
124     int x, y;
125     rep(i,1,n-1){
126         scanf("%d %d", &x, &y);
127         q[x].push_back(y);
128         q[y].push_back(x);
129     }
130     dfs(1);
131     dfs2(1,1);
132     rep(i,1,n){
133         scanf("%d", &key[w[i]]);
134     }
135     yuchu(1,tot,1);
136     int q, key;
137     scanf("%d", &q); char c[7] = {0};
138     rep(i,1,q){
139         scanf("%s", c);
140         if( c[0] == 'Q' ){
141             if( c[1] == 'S' ){
142                 scanf("%d %d", &x, &y);
143                 cout<<quire(x,y,0)<<endl;
144             }
145             else if( c[1] == 'M' ){
146                 scanf("%d %d", &x, &y);
147                 cout<<quire(x,y,1)<<endl;
148             }
149         }
150         else if( c[0] == 'C' ){
151             scanf("%d %d", &x, &key);
152             update(w[x],key,1);
153         }
154     }
155     return 0;
156 }

 

 

link-cut-tree 版本这是我一直想学的数据结构,(这个坑已经挖了好久了,直到这个星期才开始填,还好填了大半,虽然有一些还不大理解,再多做两道题吧!)

加油,相信自己。四千多毫秒,比树链剖分慢多了。  注意一开始要把mx[0] 弄得很小,否则会出错。

  1 #include<cstdio>
  2 #include<iostream>
  3 #define rep(i,j,k) for(int i = j; i <= k; i++)
  4 #define maxn 30005
  5 using namespace std;
  6 
  7 int read()
  8 {
  9     int s = 0, t = 1; char c = getchar();
 10     while( !isdigit(c) ){
 11         if( c =='-' ) t = -1; c = getchar();
 12     }
 13     while( isdigit(c) ){
 14         s = s * 10 + c - '0'; c=  getchar();
 15     }
 16     return s * t;
 17 }
 18 
 19 int mx[maxn], c[maxn][2], sum[maxn], w[maxn];
 20 int u[maxn], v[maxn], q[maxn], fa[maxn], n, m, top;
 21 bool rev[maxn];
 22 
 23 bool root(int x)
 24 {
 25     return c[fa[x]][0] != x && c[fa[x]][1] != x;
 26 }
 27 
 28 void pushdown(int x)
 29 {
 30     if( rev[x] ){
 31         int l = c[x][0], r = c[x][1];
 32         rev[x] ^= 1, rev[l] ^= 1, rev[r] ^= 1; 
 33         swap(c[x][0],c[x][1]);
 34     }
 35 }
 36 
 37 void update(int x)
 38 {
 39     int l = c[x][0], r = c[x][1];
 40     sum[x] = sum[l] + sum[r] + w[x];
 41     mx[x] = max(max(mx[l],mx[r]),w[x]);
 42 } 
 43 
 44 void rorate(int x)
 45 {
 46     int y = fa[x], z = fa[y];
 47     int l = (c[y][0] == x), r = l ^ 1; 
 48     if( !root(y) ) c[z][y==c[z][1]] = x;
 49     fa[y] = x, fa[x] = z; if( c[x][l] ) fa[c[x][l]] = y;
 50     c[y][r] = c[x][l]; c[x][l] = y; 
 51     update(y), update(x);
 52 }
 53 
 54 void splay(int x)
 55 {
 56     q[++top] = x;
 57     for(int i = x; !root(i); i=fa[i]){
 58         q[++top] = fa[i];
 59     }
 60     while( top ) pushdown(q[top--]);
 61     while( !root(x) ){
 62         int y = fa[x], z = fa[y];
 63         if( !root(y) ){
 64             if( c[y][0] == x ^ c[z][0] == y ) rorate(x);
 65             else rorate(y);
 66         }
 67         rorate(x);
 68     }
 69 }
 70 
 71 void access(int x)
 72 {
 73     for(int t = 0; x; t = x, x = fa[x]){
 74         splay(x), c[x][1] = t, update(x);
 75     }
 76 }
 77 
 78 void makeroot(int x)
 79 {
 80     access(x), splay(x); rev[x] ^= 1;
 81 }
 82 
 83 void join(int x, int y)
 84 {
 85     makeroot(x), fa[x] = y; 
 86 }
 87 
 88 void split(int x, int y)
 89 {
 90     makeroot(x), access(y), splay(y);
 91 }
 92 
 93 int main()
 94 {
 95     n = read(), mx[0] = -0x7fffffff;
 96     rep(i,1,n-1){
 97         u[i] = read(), v[i] = read();
 98     }
 99     rep(i,1,n){
100         sum[i] = w[i] = mx[i] = read();
101     }
102     rep(i,1,n-1){
103         join(u[i],v[i]);
104     }
105     m = read(); char ch[10];
106     rep(i,1,m){
107         scanf("%s", ch);
108         int u = read(), v = read();
109         if( ch[1] == 'H' ){
110             splay(u);
111             w[u] = v;
112             update(u);
113         }
114         if( ch[1] == 'M' ){
115             split(u,v); printf("%d\n", mx[v]);
116         }
117         if( ch[1] == 'S' ) {
118             split(u,v); printf("%d\n", sum[v]);
119         }
120     }
121     return 0;
122 }

 

posted on 2015-12-22 12:56  83131  阅读(131)  评论(0编辑  收藏  举报

导航