BZOJ 2001: [Hnoi2010]City 城市建设

来源:互联网 发布:xp安装不了软件 编辑:程序博客网 时间:2024/05/16 09:16

太神辣完全不会%%%%%%%%%%%%%%%%

听说可以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;}


0 0