Topic: Given a 2*n grid diagram, changing the weights of an edge multiple times or asking for the y-coordinate of the r-l+1 point in [L,r] MST
This is really a good question = =
We use segment trees to maintain MST within each interval
Then consider merging
Merge two bands We'll add two sides, so we're going to have to form a ring to cut off the biggest edge of the ring.
And then it's a messy detail. Discussion = =
First, the maximum edge must be in the color portion of the figure in the green section can be O (1) We need to maintain the red and blue parts
Then if the cut edge is sideways or cut off the vertical edge is not the only vertical edge of the interval (blue vertical edge) then the red and blue boxes directly with the left and right intervals
But if you cut out the only vertical edge of the interval (the red vertical edge in the picture), then it's a bit of a problem.
First we need to know if the cut is vertical, so we're going to record the weights of the leftmost and rightmost vertical edges of each interval's MST.
And then record the number of vertical edges on the MST in the interval.
Then if you cut the red vertical, the box on the left is updated to the maximum of "all sides of the left interval" "Green Edge" "Blue Edge"
So you have to record the maximum length of all sides of the interval.
Then update the time to discuss ... It's gone.
P.s. Finally, SDOI2015 's six questions were all over the whole afternoon. + Day I could be retired Qaq
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 60600using namespace Std;int n,m;int a[m][2],b[m];struct abcd{int l,r;//interval around endpoint int sum;//mst weight int max_val;// The maximum edge weight int cnt;//mst on all sides of the interval int l_val,r_val;//the weight of the first vertical edge of the left/right int l_max,r_max;//left/right the first vertical edge to the left/right of all tree sides with maximum weight abcd () {} ABCD (int pos) {int x=b[pos];l=r=pos;sum=x;max_val=0;cnt=1;l_val=r_val=x;l_max=r_max=x;} Friend ABCD operator + (const ABCD &x,const abcd &y) {ABCD Re;re.l=x.l;re.r=y.r;re.max_val=max (max (a[x.r][0],a[ X.R][1]), Max (x.max_val,y.max_val)), int Max_val=max (max (a[x.r][0],a[x.r][1]), Max (X.r_max,y.l_max));//Ring on the largest edge re.sum =x.sum+y.sum+a[x.r][0]+a[x.r][1]-max_val;re.cnt=x.cnt+y.cnt;re.l_val=x.l_val;re.r_val=y.r_val;re.l_max=x.l_max ; Re.r_max=y.r_max;if (X.r_val==max_val) {re.cnt--;if (x.cnt==1) {Re.l_val=y.l_val;re.l_max=max (max (x.max_val,y.l_ Max), Max (a[x.r][0],a[x.r][1]);}} else if (y.l_val==max_val) {re.cnt--;if (y.cnt==1) {Re.r_val=x.r_val;re.r_max=max (max (Y.max_val,x.r_max), MAx (a[x.r][0],a[x.r][1]));}} return re;}}; struct Segtree{segtree *ls,*rs;abcd status;void* operator new (size_t) {static Segtree mempool[m<<1],*c=mempool; return C + +;} void Build_tree (int x,int y) {int mid=x+y>>1;if (x==y) {STATUS=ABCD (mid); return;} (Ls=new segtree)->build_tree (x,mid);(rs=new segtree)->build_tree (mid+1,y);status=ls->status+rs-> status;} void Refresh1 (int x,int y,int pos) {int mid=x+y>>1;if (x==y) {STATUS=ABCD (mid); return;} if (pos<=mid) ls->refresh1 (X,mid,pos); Elsers->refresh1 (mid+1,y,pos); status=ls->status+rs->status;} void Refresh2 (int x,int y,int pos) {int mid=x+y>>1;if (mid==pos) {Status=ls->status+rs->status;return;} if (pos<=mid) Ls->refresh2 (X,mid,pos); Elsers->refresh2 (mid+1,y,pos); status=ls->status+rs->status;} ABCD Query (int x,int y,int l,int r) {int mid=x+y>>1;if (X==L&&Y==R) return status;if (R<=mid) return ls- >query (X,MID,L,R); if (L>mid) return rs->query (MID+1,Y,L,R); return Ls->query (X,Mid,l,mid) + rs->query (mid+1,y,mid+1,r);}} *root=new segtree;void Modify (int x0,int y0,int x1,int y1,int z) {if (Y0==Y1)//modified a vertical edge {B[Y0]=Z;ROOT->REFRESH1 (1,n,y0 );} else//modified a horizontal {if (y0>y1) swap (y0,y1); A[y0][x0-1]=z;root->refresh2 (1,n,y0);}} int main () {int I,x0,y0,x1,y1,x,y,z;char p[10];cin>>n>>m;for (i=1;i<n;i++) scanf ("%d", &a[i][0]); for (i=1;i<n;i++) scanf ("%d", &a[i][1]), for (i=1;i<=n;i++) scanf ("%d", &b[i]); Root->build_tree (1,n) ; for (i=1;i<=m;i++) {scanf ("%s", p), if (p[0]== ' C ') {scanf ("%d%d%d%d%d", &x0,&y0,&x1,&y1,&z); Modify (x0,y0,x1,y1,z);} ELSE{SCANF ("%d%d", &x,&y), ABCD Ans=root->query (1,n,x,y);p rintf ("%d\n", Ans.sum);}} return 0;}
Bzoj 3995 Sdoi2015 Road Construction Line Tree