bzoj 2001 [Hnoi2010]City 城市建设 cdq分治
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; typedef long long ll; #define N 50010 #define inf 0x6fffffffffLL struct P{ int x,y; ll w,org; int num; bool operator<(P a)const{ return w<a.w; } }c[N*40]; int cn; int bb[N*40],bn; int f1[N],f2[N]; int get1(int x){ return f1[x]==x?x:f1[x]=get1(f1[x]); } int get2(int x){ return f2[x]==x?x:f2[x]=get2(f2[x]); } bool he(int x,int y){ int x1=get1(x),y1=get1(y); if(x1==y1)return 0; else return f1[x1]=y1,1; } void he2(int x,int y){ int x1=get2(x),y1=get2(y); if(x1!=y1)f2[x1]=y1; } P w1[N],w2[N]; int wn1,wn2; ll ans[N]; int ch[N]; ll to[N]; int h[N]; int n,m,q; void solv(int L,int R,int cl,int cr,int bl,int br,ll res){ int rb=bn,rc=cn,p,j; wn1=0,wn2=0; for(int i=bl;i<=br;i++)f1[bb[i]]=bb[i],f2[bb[i]]=bb[i]; for(int i=cl;i<=cr;i++)w1[++wn1]=c[i],h[c[i].num]=wn1; if(L==R){ p=h[ch[L]]; w1[p].w=to[L]; sort(w1+1,w1+wn1+1); for(int i=1;i<=wn1;i++)if(he(w1[i].x,w1[i].y))res+=w1[i].w; ans[L]=res; return; } for(int i=L;i<=R;i++){ p=h[ch[i]]; if(w1[p].w==-inf)continue; w1[p].org=w1[p].w; w1[p].w=-inf; } sort(w1+1,w1+wn1+1); for(int i=1;i<=wn1;i++){ p=w1[i].x,j=w1[i].y; if(he(p,j)){ if(w1[i].w!=-inf)he2(p,j),res+=w1[i].w; } } for(int i=bl;i<=br;i++)if(f2[bb[i]]==bb[i])bb[++bn]=bb[i]; for(int i=1;i<=wn1;i++){ p=get2(w1[i].x),j=get2(w1[i].y); if(p!=j){ w2[++wn2]=w1[i]; w2[wn2].x=p,w2[wn2].y=j; } } for(int i=1;i<=wn2;i++)if(w2[i].w==-inf)w2[i].w=inf; sort(w2+1,w2+wn2+1); for(int i=bl;i<=br;i++)f1[bb[i]]=bb[i]; for(int i=1;i<=wn2;i++){ if(he(w2[i].x,w2[i].y)){ if(w2[i].w!=inf)c[++cn]=w2[i]; } } for(int i=1;i<=wn2;i++)if(w2[i].w==inf){ c[++cn]=w2[i]; c[cn].w=w2[i].org; } int mid=(L+R)>>1; int r1=cn,r2=bn; solv(L,mid,rc+1,r1,rb+1,r2,res); for(int i=rc+1;i<=r1;i++)h[c[i].num]=i; for(int i=L;i<=mid;i++)c[h[ch[i]]].w=to[i]; solv(mid+1,R,rc+1,r1,rb+1,r2,res); } int main(){ scanf("%d%d%d",&n,&m,&q); for(int i=1;i<=m;i++){ scanf("%d%d%lld",&c[i].x,&c[i].y,&c[i].w); c[i].num=i; } for(int i=1;i<=q;i++){ scanf("%d%lld",&ch[i],&to[i]); } for(int i=1;i<=n;i++)bb[i]=i; cn=m; bn=n; solv(1,q,1,m,1,n,0); for(int i=1;i<=q;i++){ printf("%lld\n",ans[i]); } }