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 }
弱者究竟为何而战?!