FZU2082 过路费

树链剖分边更新,线段树点更新,区间求和

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

 

posted on 2015-07-25 12:02  round_0  阅读(170)  评论(0编辑  收藏  举报

导航