太神辣完全不会%%%%%%%%%%%%%%%%
听说可以CDQ分治+LCT做,不过好像会被卡常数
于是找到了网上的鬼畜题解,非常玄学的做法
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=20000+5; const int M=50000+5; const int inf=1e9; typedef long long ll; struct Edge{int u,v,w,id;}e[25][M],d[M],t[M]; struct Opt{int x,y;}q[M]; int pa[N],size[N],idx[M],sum[25],wi[M]; ll ans[M]; int find(int x){ return pa[x]==x?x:pa[x]=find(pa[x]); } void merge(int x,int y){ if(size[x]>size[y])swap(x,y); size[y]+=size[x],pa[x]=y; } void init(int tot,Edge *d){ for(int i=1;i<=tot;i++) pa[d[i].u]=d[i].u, pa[d[i].v]=d[i].v, size[d[i].u]=size[d[i].v]=1; } bool cmp(Edge x,Edge y){ return x.w<y.w; } void constraction(int &tot,ll &val){ int tmp=0; init(tot,d); sort(d+1,d+1+tot,cmp); for(int i=1;i<=tot;i++) if(find(d[i].u)!=find(d[i].v)) merge(pa[d[i].u],pa[d[i].v]),t[++tmp]=d[i]; init(tmp,t); for(int i=1;i<=tmp;i++) if(t[i].w!=-inf&&find(t[i].u)!=find(t[i].v)) merge(pa[t[i].u],pa[t[i].v]),val+=t[i].w; tmp=0; for(int i=1;i<=tot;i++) if(find(d[i].u)!=find(d[i].v)){ t[++tmp]=d[i]; idx[d[i].id]=tmp; t[tmp].u=pa[d[i].u]; t[tmp].v=pa[d[i].v]; } for(int i=1;i<=tmp;i++)d[i]=t[i]; tot=tmp; } void reduction(int &tot){ int tmp=0; init(tot,d); sort(d+1,d+1+tot,cmp); for(int i=1;i<=tot;i++) if(find(d[i].u)!=find(d[i].v)){ merge(pa[d[i].u],pa[d[i].v]); t[++tmp]=d[i]; idx[d[i].id]=tmp; }else if(d[i].w==inf){ t[++tmp]=d[i]; idx[d[i].id]=tmp; } for(int i=1;i<=tmp;i++)d[i]=t[i]; tot=tmp; } void cdq(int l,int r,int layer,ll val){ int tot=sum[layer]; if(l==r)wi[q[l].x]=q[l].y; for(int i=1;i<=tot;i++){ e[layer][i].w=wi[e[layer][i].id]; d[i]=e[layer][i]; idx[d[i].id]=i; } if(l==r){ ans[l]=val; init(tot,d); sort(d+1,d+1+tot,cmp); for(int i=1;i<=tot;i++) if(find(d[i].u)!=find(d[i].v)) merge(pa[d[i].u],pa[d[i].v]),ans[l]+=d[i].w; return; } for(int i=l;i<=r;i++)d[idx[q[i].x]].w=-inf; constraction(tot,val); for(int i=l;i<=r;i++)d[idx[q[i].x]].w=inf; reduction(tot); for(int i=1;i<=tot;i++)e[layer+1][i]=d[i]; sum[layer+1]=tot; int mid=l+r>>1; cdq(l,mid,layer+1,val);cdq(mid+1,r,layer+1,val); } int main(){ //freopen("a.in","r",stdin); int n,m,Q; scanf("%d%d%d",&n,&m,&Q); for(int i=1;i<=m;i++){ scanf("%d%d%d",&e[0][i].u,&e[0][i].v,&e[0][i].w); wi[i]=e[0][i].w;e[0][i].id=i; } for(int i=1;i<=Q;i++)scanf("%d%d",&q[i].x,&q[i].y); sum[0]=m; cdq(1,Q,0,0); for(int i=1;i<=Q;i++) printf("%lld\n",ans[i]); return 0; }