POJ2763 Housewife Wind(DFS序)
题目:单边修改,树链查询。
这题是边权,不是点权,不过也可以看作是点权。
然后其实就和BZOJ2819一样。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 #define MAXN 111111 6 struct Edge{ 7 int u,v,w,nxt; 8 }edge[MAXN<<1]; 9 int n,head[MAXN],NE; 10 void addEdge(int u,int v,int w){ 11 edge[NE].u=u; edge[NE].v=v; edge[NE].w=w; edge[NE].nxt=head[u]; head[u]=NE++; 12 } 13 int odr,l[MAXN],r[MAXN],stack[MAXN],sum[MAXN],fa[20][MAXN],dep[MAXN]; 14 void dfs(){ 15 int top=0; 16 stack[++top]=1; 17 while(top){ 18 int u=stack[top]; 19 if(l[u]){ 20 r[u]=odr; --top; 21 continue; 22 } 23 l[u]=++odr; 24 for(int i=head[u]; i!=-1; i=edge[i].nxt){ 25 int v=edge[i].v; 26 if(fa[0][u]==v) continue; 27 fa[0][v]=u; dep[v]=dep[u]+1; sum[v]=sum[u]+edge[i].w; 28 stack[++top]=v; 29 } 30 } 31 } 32 33 int N,tree[MAXN<<2],x,y,z; 34 void update(int i,int j,int k){ 35 if(x<=i && j<=y){ 36 tree[k]+=z; 37 return; 38 } 39 if(tree[k]){ 40 tree[k<<1]+=tree[k]; tree[k<<1|1]+=tree[k]; 41 tree[k]=0; 42 } 43 int mid=i+j>>1; 44 if(x<=mid) update(i,mid,k<<1); 45 if(y>mid) update(mid+1,j,k<<1|1); 46 } 47 int query(int i,int j,int k){ 48 if(i==j) return tree[k]; 49 if(tree[k]){ 50 tree[k<<1]+=tree[k]; tree[k<<1|1]+=tree[k]; 51 tree[k]=0; 52 } 53 int mid=i+j>>1; 54 if(x<=mid) return query(i,mid,k<<1); 55 return query(mid+1,j,k<<1|1); 56 } 57 int lca(int u,int v){ 58 if(dep[u]>dep[v]) swap(u,v); 59 for(int k=0; k<20; ++k){ 60 if((dep[v]-dep[u])>>k&1){ 61 v=fa[k][v]; 62 } 63 } 64 if(v==u) return u; 65 for(int k=19; k>=0; --k){ 66 if(fa[k][u]!=fa[k][v]){ 67 u=fa[k][u]; 68 v=fa[k][v]; 69 } 70 } 71 return fa[0][u]; 72 } 73 void init(){ 74 dfs(); 75 for(int i=1; i<20; ++i){ 76 for(int j=1; j<=n; ++j){ 77 int t=fa[i-1][j]; 78 fa[i][j]=fa[i-1][t]; 79 } 80 } 81 for(N=1; N<odr; N<<=1); 82 for(int i=1; i<=n; ++i){ 83 x=l[i]; y=l[i]; z=sum[i]; 84 update(1,N,1); 85 } 86 } 87 88 int main(){ 89 int q,s,op,a,b,c; 90 memset(head,-1,sizeof(head)); 91 scanf("%d%d%d",&n,&q,&s); 92 for(int i=1; i<n; ++i){ 93 scanf("%d%d%d",&a,&b,&c); 94 addEdge(a,b,c); 95 addEdge(b,a,c); 96 } 97 init(); 98 while(q--){ 99 scanf("%d",&c); 100 if(c){ 101 scanf("%d%d",&a,&b); 102 Edge &e=edge[a-1<<1]; 103 if(fa[0][e.u]==e.v){ 104 x=l[e.u]; y=r[e.u]; z=b-e.w; 105 }else{ 106 x=l[e.v]; y=r[e.v]; z=b-e.w; 107 } 108 e.w=b; 109 update(1,N,1); 110 }else{ 111 scanf("%d",&a); 112 int res; 113 x=l[a]; res=query(1,N,1); 114 x=l[s]; res+=query(1,N,1); 115 x=l[lca(a,s)]; res-=(query(1,N,1)<<1); 116 s=a; 117 printf("%d\n",res); 118 } 119 } 120 return 0; 121 }