POJ2763 Housewife Wind

树链剖分边更新,线段树单点更新,区间查询

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <cstdlib>
  5 using namespace std;
  6 #define lson l,m,rt<<1
  7 #define rson m+1,r,rt<<1|1
  8 const int maxn = 100005;
  9 int siz[maxn],son[maxn],fa[maxn],dep[maxn],top[maxn],tid[maxn],lable;
 10 int head[maxn],cnt;
 11 struct edge
 12 {
 13     int v,w,en,next;
 14 }e[maxn*2];
 15 int n,m,s;
 16 int sum[maxn<<2];
 17 void init()
 18 {
 19     memset(head,-1,sizeof(head));
 20     cnt = lable = 0;
 21 }
 22 void add(int u,int v,int w)
 23 {
 24     e[cnt].v = v;
 25     e[cnt].w = w;
 26     e[cnt].next = head[u];
 27     head[u] = cnt++;
 28 }
 29 void find_heavy(int rt,int father,int depth)
 30 {
 31 //printf("rt=%d fa=%d \n",rt,father);
 32     fa[rt] = father;
 33     son[rt] = 0;
 34     dep[rt] = depth;
 35     siz[rt] = 1;
 36     int maxsize = 0;
 37     for(int i = head[rt];i!=-1;i = e[i].next)if(e[i].v!=father)
 38     {
 39         e[i].en = e[i^1].en = e[i].v;
 40         find_heavy(e[i].v,rt,depth+1);
 41         siz[rt]+=siz[e[i].v];
 42         if(siz[e[i].v]>maxsize)
 43             maxsize = siz[e[i].v],son[rt] = e[i].v;
 44     }
 45 }
 46 void connect(int rt,int anc)
 47 {
 48     tid[rt] = ++lable;
 49     top[rt] = anc;
 50     if(son[rt])connect(son[rt],anc);
 51     for(int i = head[rt];i!=-1;i = e[i].next)
 52         if(e[i].v!=fa[rt]&&e[i].v!=son[rt])
 53             connect(e[i].v,e[i].v);
 54 }
 55 void pushup(int rt)
 56 {
 57     sum[rt] = sum[rt<<1]+sum[rt<<1|1];
 58 }
 59 void update(int pos,int val,int l,int r,int rt)
 60 {
 61     if(l==r){
 62         sum[rt] = val;
 63         return;
 64     }
 65     int m = (l+r)>>1;
 66     if(pos<=m)update(pos,val,lson);
 67     else update(pos,val,rson);
 68     pushup(rt);
 69 }
 70 int query(int L,int R,int l,int r,int rt)
 71 {
 72     if(L<=l&&r<=R)return sum[rt];
 73     int m = (l+r)>>1,ret = 0;
 74     if(L<=m)ret+=query(L,R,lson);
 75     if(m<R)ret+=query(L,R,rson);
 76     return ret;
 77 }
 78 int getsum(int x,int y)
 79 {
 80     int ans = 0;
 81     while(top[x]!=top[y])
 82     {
 83         if(dep[top[x]]<dep[top[y]])swap(x,y);
 84         ans+=query(tid[top[x]],tid[x],1,n,1);
 85         x = fa[top[x]];
 86     }
 87     if(dep[x]>dep[y])swap(x,y);
 88     if(x==y)return ans;
 89     ans+=query(tid[son[x]],tid[y],1,n,1);
 90     return ans;
 91 }
 92 int main()
 93 {
 94     while(~scanf("%d%d%d",&n,&m,&s))
 95     {
 96         init();
 97         for(int i = 1;i<n;++i)
 98         {
 99             int u,v,w;scanf("%d%d%d",&u,&v,&w);
100             add(u,v,w);
101             add(v,u,w);
102         }
103 //        for(int i = 1;i<=n;++i){
104 //            printf("i=%d:",i);
105 //            for(int j = head[i];j!=-1;j = e[j].next)
106 //            {
107 //                printf("%d ",e[j].v);
108 //                system("pause");
109 //            }
110 //            puts("");
111 //        }
112         find_heavy(1,1,1);//puts("----------");
113         connect(1,1);
114 
115         for(int i = 0;i<cnt;i+=2)update(tid[e[i].en],e[i].w,1,n,1);
116         while(m--)
117         {
118             int a,b,c;scanf("%d",&a);
119             if(a){
120                 scanf("%d%d",&b,&c);
121                 update(tid[e[2*b-1].en],c,1,n,1);
122             }
123             else {
124                 scanf("%d",&b);
125                 printf("%d\n",getsum(s,b));
126                 s = b;
127             }
128         }
129     }
130     return 0;
131 }

 

posted on 2015-07-25 11:57  round_0  阅读(171)  评论(0编辑  收藏  举报

导航