poj2763
树状数组记录各点到根的距离。边值变化时,深度大的点的bg[]树状数组中增加,fn[]+1减。树状数组中x位置变化影响的是>=x的数。这样bg[]+,fn[]+1 减,这样就能消除影响。
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <iomanip> #include <cstring> #include <map> #include <queue> #include <set> #include <cassert> #include <stack> #include <bitset> //#include <unordered_set> #define mkp make_pair #define err cout<<"here"<<endl using namespace std; const double EPS=1e-12; typedef long long lon; typedef unsigned long long ull; typedef map<ull,int>::iterator IT; const lon SZ=100010,SSZ=1000010,APB=20,mod=100000,one=97; const lon INF=0x7FFFFFFF; lon n,bg[SZ],fn[SZ],cnt,dp[SZ][APB]; int dst[SZ],sum[SZ],dep[SZ]; struct nd{ lon to,wt; nd(lon a=0,lon b=0):to(a),wt(b){} }; int head[SZ],nex[SSZ],to[SSZ],wt[SSZ]; int tot=-1; void add_edge(int u,int v,int w) { ++tot; nex[tot]=head[u]; head[u]=tot; to[tot]=v,wt[tot]=w; } struct pt{ int u,v,w; pt(int a=0,int b=0,int c=0):u(a),v(b),w(c){} }; pt arr[SZ]; void dfs1(int x,int p,int y,int d) { bg[x]=++cnt; if(p!=-1)dp[x][0]=p; dst[x]=y,dep[x]=d; for(int i=1;i<APB;++i) { dp[x][i]=dp[dp[x][i-1]][i-1]; } for(int i=head[x];i!=-1;i=nex[i]) { int t=to[i]; int w=wt[i]; if(t!=p) { dfs1(t,x,y+w,d+1); } } fn[x]=cnt; } int lowbit(int x) { return x&-x; } void add(int x,int val) { if(x<=0)return; for(;x<SZ;x+=lowbit(x)) { sum[x]+=val; } } int qry(int x) { int res=0; for(;x>0;x-=lowbit(x)) { res+=sum[x]; } return res; } int lca(int x,int y) { if(dep[x]<dep[y])swap(x,y); for(int i=APB-1;i>=0;--i) { if(dep[dp[x][i]]>=dep[y]) { x=dp[x][i]; } } if(x==y)return x; for(int i=APB-1;i>=0;--i) { if(dp[x][i]!=dp[y][i]) { x=dp[x][i]; y=dp[y][i]; } } return dp[x][0]; } void init() { int qnum,cur; cin>>n>>qnum>>cur; memset(head,-1,sizeof(head)); for(int i=1;i<=n-1;++i) { int a,b,c; //cin>>a>>b>>c; scanf("%d%d%d",&a,&b,&c); add_edge(a,b,c); add_edge(b,a,c); arr[i]=pt(a,b,c); } dfs1(1,-1,0,1); // for(int i=1;i<=n-1;++i) // { // int u=arr[i].u; // int v=arr[i].v; // int w=arr[i].w; // if(dep[u]<dep[v])swap(u,v); // add(bg[u],w); // add(fn[u]+1,-w); // } for(int i=1;i<=n;++i) { add(bg[i],dst[i]); add(bg[i]+1,-dst[i]); //cout<<"i: "<<i<<" "<<bg[i]<<" "<<dst[i]<<endl; //if(bg[i]!=1)add(bg[i]-1,-dst[i]); } for(int i=1;i<=qnum;++i) { int type; //cin>>type; scanf("%d",&type); if(!type) { int pos; //cin>>pos; scanf("%d",&pos); int res=0; //pos=3; res+=qry(bg[pos]);//-qry(bg[pos]-1); res+=qry(bg[cur]);//-qry(bg[cur]-1); //cout<<"cur: "<<cur<<endl; int tmp=bg[lca(pos,cur)]; res-=2*qry(tmp);//2*(qry(tmp)-qry(tmp-1)); //cout<<res<<endl; printf("%d\n",res); cur=pos; } else { int id,val; //cin>>id>>val; scanf("%d%d",&id,&val); int u=arr[id].u; int v=arr[id].v; int lw=dep[u]>dep[v]?u:v; int delta=val-arr[id].w; add(fn[lw]+1,-delta); add(bg[lw],delta); arr[id].w=val; } } } void work() { } void release() { } int main() { //std::ios::sync_with_stdio(0); //freopen("d:\\1.txt","r",stdin); lon casenum; //cin>>casenum; //cout<<casenum<<endl; //for(lon time=1;time<=casenum;++time) //for(lon time=1;cin>>m>>n;++time) { init(); work(); release(); } return 0; }
浙公网安备 33010602011771号