zoukankan      html  css  js  c++  java
  • POJ2763-Housewife Wind-树上单点修改区间求和

    这道题可以树链剖分做。但是最近在给学弟搞数据结构复习了LCA树状数组RMQ

    然后就搞了一发LCA+树状数组维护。

    dis数组维护当前点到根节点的权值和。则dis(u,v) = dis[u]+dis[v]-2*dis[lca(u,v)]

    修改的时候,单点修改影响了该点所有儿子的dis,刚好可以用dfs序定位所有儿子,用树状数组改段求点很方便。

    http://blog.csdn.net/q573290534/article/details/6664454 树状数组的三种求和(改点求段,改段求点,改段求段)

    http://blog.csdn.net/qwe2434127/article/details/49819975 dfs序题目类型

    http://www.cnblogs.com/longdouhzt/archive/2011/10/16/2214034.html LCA题目小节

      1 #include <cstdio>
      2 #include <cmath>
      3 #include <cstring>
      4 #include <algorithm>
      5 
      6 using namespace std;
      7 
      8 const int maxn = 2e5+100;
      9 
     10 int N,Q,S;
     11 //vector <int> G[maxn];
     12 
     13 struct edge{
     14     int to,next,w;
     15 }e[2*maxn];
     16 
     17 int head[2*maxn],tot;
     18 void add_edge(int u,int v,int w)
     19 {
     20     e[tot].to = v;
     21     e[tot].w = w;
     22     e[tot].next = head[u];
     23     head[u] = tot++;
     24 
     25     e[tot].to = u;
     26     e[tot].w = w;
     27     e[tot].next = head[v];
     28     head[v] = tot++;
     29 }
     30 
     31 int in[maxn],out[maxn],P[2*maxn],fa[maxn][30],dep[maxn],dis[maxn],cnt;
     32 void dfs(int u,int _fa,int _dep,int _dis)
     33 {
     34     in[u] = ++cnt;
     35     P[cnt] = u;
     36     fa[u][0] = _fa;
     37     dis[u] = _dis;
     38     dep[u] = _dep;
     39     for(int i=head[u];~i;i=e[i].next)
     40     {
     41         int v = e[i].to;
     42         if(v == _fa) continue;
     43         dfs(v,u,_dep+1,_dis+e[i].w);
     44     }
     45     out[u] = ++cnt;
     46 }
     47 void debug()
     48 {
     49     printf("in:	");for(int i=1;i<=N;i++) printf("%d ",in[i]);puts("");
     50     printf("out:	");for(int i=1;i<=N;i++) printf("%d ",out[i]);puts("");
     51     printf("p:	");for(int i=1;i<=cnt;i++) printf("%d ",P[i]);puts("");
     52     printf("dis:	");for(int i=1;i<=N;i++) printf("%d ",dis[i]);puts("");
     53     printf("dep:	");for(int i=1;i<=N;i++) printf("%d ",dep[i]);puts("");
     54     printf("edge:");for(int i=0;i<tot;i++) printf("	to:%d w:%d
    ",e[i].to,e[i].w);
     55 }
     56 
     57 int initLCA()
     58 {
     59     int m = (int)log(N)/log(2)+1;
     60     for(int k=0;k<m;k++)
     61     {
     62         for(int v=1;v<=N;v++)
     63         {
     64             if(fa[v][k] < 0) {fa[v][k+1] = -1;continue;}
     65             else fa[v][k+1] = fa[fa[v][k]][k];
     66         }
     67     }
     68 }
     69 
     70 int LCA(int u,int v)
     71 {
     72     int m = (int)log(N)/log(2)+1;
     73     if(dep[v] > dep[u]) swap(u,v);
     74     for(int k=0;k<m;k++)
     75     {
     76         if((dep[u]-dep[v])>>k & 1 )
     77             u = fa[u][k];
     78     }
     79     if(u == v) return u;
     80     for(int k=m-1;k>=0;k--)
     81     {
     82         if(fa[u][k] != fa[v][k])
     83         {
     84             u = fa[u][k];
     85             v = fa[v][k];
     86         }
     87     }
     88     return fa[u][0];
     89 }
     90 
     91 int c[2*maxn];
     92 int lowbit(int x) {return x&-x;}
     93 
     94 void init()
     95 {
     96     memset(head,-1,sizeof head);
     97     memset(fa,-1,sizeof fa);
     98     memset(c,0,sizeof c);
     99     memset(in,0,sizeof in);
    100     memset(out,0,sizeof out);
    101     tot = 0;
    102     cnt = 0;
    103 }
    104 
    105 void add(int x,int d)
    106 {
    107     while(x)
    108     {
    109         c[x] += d;
    110         x -= lowbit(x);
    111     }
    112 }
    113 void add_seg(int l,int r,int d)
    114 {
    115     add(r,d);
    116     add(l-1,-d);
    117 }
    118 int sum(int x)
    119 {
    120     int res = 0;
    121     //printf("u:%d ",P[x]);
    122     while(x <= cnt)
    123     {
    124         res += c[x];
    125         x += lowbit(x);
    126     }
    127     //printf("res:%d
    ",res);
    128     return res;
    129 }
    130 int dist(int x)
    131 {
    132     if(x == -1) return 0;
    133     return sum(in[x]) + dis[x];
    134 }
    135 int main()
    136 {
    137     //freopen("input.txt","r",stdin);
    138     while(~scanf("%d%d%d",&N,&Q,&S))
    139     {
    140         init();
    141         for(int i=0,u,v,w;i<N-1;i++)
    142         {
    143             scanf("%d%d%d",&u,&v,&w);
    144             add_edge(u,v,w);
    145         }
    146         dfs(1,-1,1,0);
    147         //debug();
    148         initLCA();
    149         for(int i=0;i<tot;i+=2)
    150         {
    151             if(dep[e[i].to] < dep[e[i+1].to]) swap(e[i].to,e[i+1].to);
    152         }
    153         int op;
    154         for(int i=0,a,b,c;i<Q;i++)
    155         {
    156             scanf("%d",&op);
    157             if(op == 0)
    158             {
    159                 scanf("%d",&a);
    160                 int lca = LCA(S,a);
    161                 //printf("lca:%d
    ",lca);
    162 
    163                 printf("%d
    ",dist(S)+dist(a)-2*(dist(lca)));
    164                 S = a;
    165             }else
    166             {
    167                 scanf("%d%d",&a,&b);
    168                 a--;
    169                 int u = e[a*2].to;
    170                 int dw = b - (dist(u) - dist(fa[u][0]));
    171                 //printf("dw:%d u:%d
    ",dw,u);
    172                 add_seg(in[u],out[u],dw);
    173             }
    174         }
    175     }
    176 }
  • 相关阅读:
    Python学习第七天——随机码生成
    Python学习第六天——Fibonacci
    Python学习第五天——递归函数
    Python学习第四天——文件修改
    Python学习第三天——三级目录
    Python学习第二天——购物车程序
    Python学习第一天——用户名登录退出
    Linux什么时候在pc机上有一席之地
    关于系统设计时性能以及可扩展性的考虑
    HyberLedger Fabric学习(4)-chaincode学习(操作人员)
  • 原文地址:https://www.cnblogs.com/helica/p/5713205.html
Copyright © 2011-2022 走看看