【线段树】bzoj3995 [SDOI2015]道路修建
线段树每个结点维护5个域:
整个区间的MST。
将两个左端点连通,两个右端点不连通,整个区间内选择2*(r-l+1)-2条边的最小生成森林,有两个连通块。
将两个右端点连通,两个左端点不连通,整个区间内选择2*(r-l+1)-2条边的最小生成森林,有两个连通块。
两个左端点不连通,两个右端点也不连通,整个区间内选择2*(r-l+1)-2条边的最小生成森林,有两个连通块。(就是上面一条线,下面一条线)
两个左端点不连通,两个右端点也不连通,整个区间内选择2*(r-l+1)-3条边的最小生成森林,有3个连通块。
合并时讨论5*5*2(两条夹缝里的横边是否都选择)种情况。
/*每个结点维护5个域:左右完全连通,左连通右不连通,右连通左不连通,左右都不连通2,左右都不连通3*/ #include<cstdio> #include<algorithm> using namespace std; #define N 60001 #define INF 1000000000 int n,m,heng[2][N],zong[N]; struct Node { int z1y1,z1y0,z0y1,z0y02,z0y03; void reset(){z1y1=z1y0=z0y1=z0y02=z0y03=INF;} }T[N<<2]; inline void pushup(Node &rt,const Node &ls,const Node &rs,const int &r1,const int &l1,const int &l2) { rt.reset(); int MIN=min(heng[0][r1],heng[1][r1]),SUM=heng[0][r1]+heng[1][r1]; /*z1y1+z1y1*/rt.z1y1=ls.z1y1+rs.z1y1+MIN; if(l2>1)/*z1y1+z1y0*/rt.z1y0=ls.z1y1+rs.z1y0+MIN; if(l2>1)/*z1y1+z0y1*/rt.z1y1=min(rt.z1y1,ls.z1y1+rs.z0y1+SUM); /*z1y1+z0y02*/rt.z1y1=min(rt.z1y1,ls.z1y1+rs.z0y02+SUM); rt.z1y0=min(rt.z1y0,ls.z1y1+rs.z0y02+MIN); if(l2>1)/*z1y1+z0y03*/rt.z1y0=min(rt.z1y0,ls.z1y1+rs.z0y03+SUM); if(l1>1)/*z1y0+z1y1*/rt.z1y1=min(rt.z1y1,ls.z1y0+rs.z1y1+SUM); if(l1>1&&l2>1)/*z1y0+z1y0*/rt.z1y0=min(rt.z1y0,ls.z1y0+rs.z1y0+SUM); /*z1y0+z0y1不合法*/ if(l1>1)/*z1y0+z0y02*/rt.z1y0=min(rt.z1y0,ls.z1y0+rs.z0y02+SUM); /*z1y0+z0y03不合法*/ if(l1>1)/*z0y1+z1y1*/rt.z0y1=ls.z0y1+rs.z1y1+MIN; if(l1>1&&l2>1)/*z0y1+z1y0*/rt.z0y03=ls.z0y1+rs.z1y0+MIN; if(l1>1&&l2>1)/*z0y1+z0y1*/rt.z0y1=min(rt.z0y1,ls.z0y1+rs.z0y1+SUM); if(l1>1)/*z0y1+z0y02*/rt.z0y1=min(rt.z0y1,ls.z0y1+rs.z0y02+SUM), rt.z0y03=min(rt.z0y03,ls.z0y1+rs.z0y02+MIN); if(l1>1&&l2>1)/*z0y1+z0y03*/rt.z0y03=min(rt.z0y03,ls.z0y1+rs.z0y03+SUM); /*z0y02+z1y1*/rt.z1y1=min(rt.z1y1,ls.z0y02+rs.z1y1+SUM); rt.z0y1=min(rt.z0y1,ls.z0y02+rs.z1y1+MIN); if(l2>1)/*z0y02+z1y0*/rt.z1y0=min(rt.z1y0,ls.z0y02+rs.z1y0+SUM), rt.z0y03=min(rt.z0y03,ls.z0y02+rs.z1y0+MIN); if(l2>1)/*z0y02+z0y1*/rt.z0y1=min(rt.z0y1,ls.z0y02+rs.z0y1+SUM); /*z0y02+z0y02*/rt.z0y02=ls.z0y02+rs.z0y02+SUM; rt.z0y03=min(rt.z0y03,ls.z0y02+rs.z0y02+MIN); if(l2>1)/*z0y02+z0y03*/rt.z0y03=min(rt.z0y03,ls.z0y02+rs.z0y03+SUM); if(l1>1)/*z0y03+z1y1*/rt.z0y1=min(rt.z0y1,ls.z0y03+rs.z1y1+SUM); if(l1>1&&l2>1)/*z0y03+z1y0*/rt.z0y03=min(rt.z0y03,ls.z0y03+rs.z1y0+SUM); /*z0y03+z0y1不合法*/ if(l1>1)/*z0y03+z0y02*/rt.z0y03=min(rt.z0y03,ls.z0y03+rs.z0y02+SUM); /*z0y03+z0y03不合法*/ } void buildtree(int rt,int l,int r) { if(l==r) { T[rt].z1y1=zong[l]; return; } int m=(l+r>>1); buildtree(rt<<1,l,m); buildtree(rt<<1|1,m+1,r); pushup(T[rt],T[rt<<1],T[rt<<1|1],m,m-l+1,r-m); } void update(int p,int v,int rt,int l,int r) { if(l==r) { zong[p]=v; T[rt].z1y1=v; return; } int m=(l+r>>1); if(p<=m) update(p,v,rt<<1,l,m); else update(p,v,rt<<1|1,m+1,r); pushup(T[rt],T[rt<<1],T[rt<<1|1],m,m-l+1,r-m); } void update(int p,int rt,int l,int r) { if(l==r) return; int m=(l+r>>1); if(p<=m) update(p,rt<<1,l,m); else update(p,rt<<1|1,m+1,r); pushup(T[rt],T[rt<<1],T[rt<<1|1],m,m-l+1,r-m); } Node query(int ql,int qr,int rt,int l,int r) { if(ql<=l && r<=qr) return T[rt]; int m=(l+r>>1); if(ql<=m && m<qr) { Node res; pushup(res,query(ql,qr,rt<<1,l,m),query(ql,qr,rt<<1|1,m+1,r),m,m-l+1,r-m); return res; } else if(ql<=m) return query(ql,qr,rt<<1,l,m); else return query(ql,qr,rt<<1|1,m+1,r); } int main() { // freopen("bzoj3995.in","r",stdin); // freopen("bzoj3995.out","w",stdout); for(int i=1;i<=500000;++i); scanf("%d%d",&n,&m); for(int i=0;i<2;++i) for(int j=1;j<n;++j) scanf("%d",&heng[i][j]); for(int i=1;i<=n;++i) scanf("%d",&zong[i]); buildtree(1,1,n); // printf("%d\n",query(1,3,1,1,n).z1y1); // printf("%d\n",query(1,3,1,1,n).z1y0); // printf("%d\n",query(1,3,1,1,n).z0y1); // printf("%d\n",query(1,3,1,1,n).z0y02); // printf("%d\n",query(1,3,1,1,n).z0y03); char op[3]; int x1,y1,x2,y2,val; for(;m;--m) { scanf("%s",op); if(op[0]=='C') { scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&val); if(y1==y2) update(y1,val,1,1,n); else { if(y1>y2) swap(y1,y2); heng[x1-1][y1]=val; update(y1,1,1,n); update(y2,1,1,n); } } else { scanf("%d%d",&y1,&y2); printf("%d\n",query(y1,y2,1,1,n).z1y1); } } return 0; }
——The Solution By AutSky_JadeK From UESTC
转载请注明出处:http://www.cnblogs.com/autsky-jadek/