图论:树链剖分-边权
给一个数,边之间有权值,然后两种操作,第一种:求任意两点的权值和,第二,修改树上两点的权值
1 #include <cstdio> 2 #include <cstring> 3 #include <vector> 4 #include <algorithm> 5 using namespace std; 6 #define Del(a,b) memset(a,b,sizeof(a)) 7 const int N = 100005; 8 9 int dep[N],siz[N],fa[N],id[N],son[N],val[N],top[N]; //top 最近的重链父节点 10 int num,head[N],cnt; 11 struct Edge 12 { 13 int to,next; 14 }; 15 Edge v[N*2]; 16 struct tree 17 { 18 int x,y,val; 19 void read(){ 20 scanf("%d%d%d",&x,&y,&val); 21 } 22 }; 23 void add_Node(int x,int y) 24 { 25 v[cnt].to = y; 26 v[cnt].next = head[x]; 27 head[x] = cnt++; 28 } 29 tree e[N]; 30 void dfs1(int u, int f, int d) { 31 dep[u] = d; 32 siz[u] = 1; 33 son[u] = 0; 34 fa[u] = f; 35 for(int i = head[u]; i != -1 ;i = v[i].next) 36 { 37 int to = v[i].to; 38 if(to != f) 39 { 40 dfs1(to,u,d+1); 41 siz[u] += siz[to]; 42 if(siz[son[u]] < siz[to]) 43 son[u] = to; 44 } 45 } 46 } 47 void dfs2(int u, int tp) { 48 top[u] = tp; 49 id[u] = ++num; 50 if (son[u]) dfs2(son[u], tp); 51 for(int i = head[u]; i != -1 ;i = v[i].next ) 52 { 53 int to = v[i].to; 54 if(to == fa[u] || to == son[u]) 55 continue; 56 dfs2(to,to); 57 } 58 } 59 #define lson(x) ((x<<1)) 60 #define rson(x) ((x<<1)+1) 61 struct Tree 62 { 63 int l,r,val; 64 }; 65 Tree tree[4*N]; 66 void pushup(int x) { 67 tree[x].val = tree[lson(x)].val + tree[rson(x)].val; 68 } 69 70 void build(int l,int r,int v) 71 { 72 tree[v].l=l; 73 tree[v].r=r; 74 if(l==r){ 75 tree[v].val = val[l]; 76 return ; 77 } 78 int mid=(l+r)>>1; 79 build(l,mid,v*2); 80 build(mid+1,r,v*2+1); 81 pushup(v); 82 } 83 void update(int o,int v,int val) //log(n) 84 { 85 if(tree[o].l==tree[o].r) 86 { 87 tree[o].val = val; 88 return ; 89 } 90 int mid = (tree[o].l+tree[o].r)/2; 91 if(v<=mid) 92 update(o*2,v,val); 93 else 94 update(o*2+1,v,val); 95 pushup(o); 96 } 97 int query(int o,int l, int r) 98 { 99 if (tree[o].l >= l && tree[o].r <= r) { 100 return tree[o].val; 101 } 102 int mid = (tree[o].l + tree[o].r) / 2; 103 if(r<=mid) 104 return query(o+o,l,r); 105 else if(l>mid) 106 return query(o+o+1,l,r); 107 else 108 return query(o+o,l,mid) + query(o+o+1,mid+1,r); 109 } 110 111 int Yougth(int u, int v) { 112 int tp1 = top[u], tp2 = top[v]; 113 int ans = 0; 114 while (tp1 != tp2) { 115 if (dep[tp1] < dep[tp2]) { 116 swap(tp1, tp2); 117 swap(u, v); 118 } 119 ans += query(1,id[tp1], id[u]); 120 u = fa[tp1]; 121 tp1 = top[u]; 122 } 123 if (u == v) return ans; 124 if (dep[u] > dep[v]) swap(u, v); 125 ans += query(1,id[son[u]], id[v]); 126 return ans; 127 } 128 int main() 129 { 130 int n,m,s; 131 while(~scanf("%d%d%d",&n,&m,&s)) 132 { 133 cnt = 0; 134 memset(head,-1,sizeof(head)); 135 for(int i=1;i<n;i++) 136 { 137 e[i].read(); 138 add_Node(e[i].x,e[i].y); 139 add_Node(e[i].y,e[i].x); 140 } 141 num = 0; 142 dfs1(1,0,1); 143 dfs2(1,1); 144 for(int i=1;i<n;i++) 145 { 146 if(dep[e[i].x] < dep[e[i].y]) 147 swap(e[i].x,e[i].y); 148 val[id[e[i].x]] = e[i].val; 149 } 150 build(1,num,1); 151 for(int i=0;i<m;i++) 152 { 153 int ok,x,y; 154 scanf("%d",&ok); 155 if(ok==0) 156 { 157 scanf("%d",&x); 158 printf("%d\n",Yougth(s,x)); 159 s = x; 160 } 161 else 162 { 163 scanf("%d%d",&x,&y); 164 update(1,id[e[x].x],y); 165 } 166 } 167 } 168 return 0; 169 }