zoukankan      html  css  js  c++  java
  • 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
    ", mx[v]);
    116         }
    117         if( ch[1] == 'S' ) {
    118             split(u,v); printf("%d
    ", sum[v]);
    119         }
    120     }
    121     return 0;
    122 }
    人一我十,人十我万!追逐青春的梦想,怀着自信的心,永不放弃!仿佛已看到希望,尽管还在远方
  • 相关阅读:
    MYSQL关键字的使用
    SESSION的使用
    COOKIE的使用
    ES6中的let与const---let与var的区别---详解
    JavaScript中四种数据类型检测的方法
    java数据类型
    讲Windows7的电脑搭建成服务器的教程
    ISS服务器
    用java编写一个万年历程序
    if 条件语句的用法
  • 原文地址:https://www.cnblogs.com/83131yyl/p/5066315.html
Copyright © 2011-2022 走看看