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
",res);
118         }
119     }
120     return 0;
121 }
原文地址:https://www.cnblogs.com/WABoss/p/4889625.html