1. 程式人生 > >POJ-2763-Housewife Wind(LCA+dfs序線段樹)

POJ-2763-Housewife Wind(LCA+dfs序線段樹)

有邊權修改的樹中兩點距離查詢。
因為有邊權修改,所以用線段樹維護到根的序列。
LCA求距離。
這題有個坑點就是不能用vector

#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
const int maxn=1e5+7;
int a[maxn],d[maxn],deep[maxn],len[maxn],lz[maxn<<2],f[maxn],anc[maxn][20];
int head[maxn];
int n,m,h,tot;
struct
Edge { int u,v,d,next; Edge(){} Edge(int _v,int _d):v(_v),d(_d){} Edge(int _u,int _v,int _d):u(_u),v(_v),d(_d){} }; Edge e[maxn<<1]; int dfs(int u,int pre,int deep,int dis) { anc[u][0]=pre; a[++m]=u; f[u]=m; ::deep[u]=deep; d[u]=dis; int cnt=1; for(int
i=head[u];i!=-1;i=e[i].next) { int v=e[i].v; if(v==pre) continue; cnt+=dfs(v,u,deep+1,dis+e[i].d); } return len[u]=cnt; } inline void push_down(int rt) { if(!lz[rt]) return; lz[rt<<1]+=lz[rt]; lz[rt<<1|1]+=lz[rt]; lz[rt]=0; } void update(int
rt,int l,int r,int ql,int qr,int val) { if(l>=ql&&r<=qr) { lz[rt]+=val; return ; } push_down(rt); int mid=(l+r)>>1; if(ql<=mid) update(rt<<1,l,mid,ql,qr,val); if(qr>mid) update(rt<<1|1,mid+1,r,ql,qr,val); } void query(int rt,int l,int r,int p) { if(l==r) { d[a[p]]+=lz[rt]; lz[rt]=0; return ; } push_down(rt); int mid=(l+r)>>1; if(p<=mid) query(rt<<1,l,mid,p); else query(rt<<1|1,mid+1,r,p); } inline void init() { for(int j=1;(1<<j)<n;j++) { h=j; for(int i=1;i<=n;i++) anc[i][j]=anc[i][j-1]==-1?-1:anc[anc[i][j-1]][j-1]; } } inline int lca(int u,int v) { if(deep[u]<deep[v]) swap(u,v); for(int j=h;j>=0;j--) if(deep[u]-(1<<j)>=deep[v]) u=anc[u][j]; if(u==v) return u; for(int j=h;j>=0;j--) if(anc[u][j]!=anc[v][j]) u=anc[u][j],v=anc[v][j]; return anc[u][0]; } inline void addedge(int u, int v, int c) { e[tot].u=u;e[tot].v=v;e[tot].d=c; e[tot].next=head[u]; head[u]=tot; ++tot; } int main() { int q,s; while(~scanf("%d%d%d",&n,&q,&s)) { m=0; int u,v,c,op,rid; tot=0; memset(head,-1,sizeof(head)); memset(lz,0,sizeof(int)*((n+3)<<2)); for(int i=1;i<n;i++) { scanf("%d%d%d",&u,&v,&c); addedge(u,v,c); addedge(v,u,c); } dfs(1,-1,1,0); init(); while(q--) { scanf("%d",&op); if(op) { scanf("%d%d",&rid,&c); rid=(rid-1)<<1; u=e[rid].u;v=e[rid].v; if(deep[u]<deep[v]) swap(u,v); if(f[u]<0||f[u]+len[u]-1>n) return 0; update(1,1,n,f[u],f[u]+len[u]-1,c-e[rid].d); e[rid].d=e[rid^1].d=c; } else { scanf("%d",&v); u=s; int fa=lca(u,v); query(1,1,n,f[u]); query(1,1,n,f[v]); query(1,1,n,f[fa]); printf("%d\n",d[u]+d[v]-2*d[fa]); s=v; } } } return 0; }