题意:
给一张2×n的网格图,只有相邻的点连了边,支持询问区间的最小生成树,以及修改边权。
题解:线段树。
%%%PoPoQQQ : http://blog.csdn.net/popoqqq/article/details/45080183
#include<bits/stdc++.h>
using namespace std;
struct IO{
streambuf *ib,*ob;
inline void init(){
ios::sync_with_stdio(false);
cin.tie(NULL);cout.tie(NULL);
ib=cin.rdbuf();ob=cout.rdbuf();
}
inline int read(){
char ch=ib->sbumpc();int i=0,f=1;
while(!isdigit(ch)){if(ch=='-')f=-1;ch=ib->sbumpc();}
while(isdigit(ch)){i=(i+(i<<2)<<1)+ch-'0';ch=ib->sbumpc();}
return i*f;
}
inline void W(long long x){
static int buf[50];
if(!x){ob->sputc('0');ob->sputc('\n');return;}
if(x<0){ob->sputc('-');x=-x;}
while(x){buf[++buf[0]]=x%10;x/=10;}
while(buf[0])ob->sputc(buf[buf[0]--]+'0');
ob->sputc('\n');
}
}io;
const int Maxn=3e5+50;
int n,m,v[3][Maxn];
struct node{
node *lc,*rc;
int sum,posl,posr,cntline,mxl,mxr,mxall;
inline void upt(int pos,node *x,node *y){
int mx=max(v[1][pos],max(v[2][pos],max(x->mxr,y->mxl)));
mxall=max(x->mxall,max(y->mxall,max(v[1][pos],v[2][pos])));
cntline=x->cntline+y->cntline;
if(mx==x->mxr){
sum=x->sum+y->sum-x->mxr+v[1][pos]+v[2][pos];
posr=y->posr;mxr=y->mxr;
if(v[0][x->posr]==x->mxr){
cntline--;
if(x->cntline==1){
posl=y->posl;
mxl=max(x->mxall,max(y->mxl,max(v[1][pos],v[2][pos])));
}
else posl=x->posl,mxl=x->mxl;
}
else posl=x->posl,mxl=x->mxl;
}
else if(mx==y->mxl){
sum=x->sum+y->sum-y->mxl+v[1][pos]+v[2][pos];
posl=x->posl;mxl=x->mxl;
if(v[0][y->posl]==y->mxl){
cntline--;
if(y->cntline==1){
posr=x->posr;
mxr=max(y->mxall,max(x->mxr,max(v[1][pos],v[2][pos])));
}
else posr=y->posr,mxr=y->mxr;
}
else posr=y->posr,mxr=y->mxr;
}
else {
sum=x->sum+y->sum+(mx==v[1][pos]?v[2][pos]:v[1][pos]);
posl=x->posl;posr=y->posr;
mxl=x->mxl;mxr=y->mxr;
}
}
}Pool[Maxn],*pool=Pool,*null=Pool;
inline node* newnode(){
++pool;pool->lc=pool->rc=null;
return pool;
}
struct SegmentTree{
node *rt,*que[Maxn];
int tail,rpos[Maxn];
SegmentTree():rt(null){}
inline void build(node *&now,int l,int r){
now=newnode();
if(l==r){
now->sum=now->mxl=now->mxr=v[0][l];
now->posl=now->posr=l;
now->cntline=1;
return;
}
int mid=(l+r)>>1;
build(now->lc,l,mid);
build(now->rc,mid+1,r);
now->upt(mid,now->lc,now->rc);
}
inline void findpos(node *now,int l,int r,int L,int R){
if(L<=l&&r<=R){que[++tail]=now;rpos[tail]=r;return;}
int mid=(l+r)>>1;
if(L<=mid)findpos(now->lc,l,mid,L,R);
if(R>mid)findpos(now->rc,mid+1,r,L,R);
}
inline int query(int L,int R){
tail=0;
findpos(rt,1,n,L,R);
if(tail==1)return que[tail]->sum;
node tmp;tmp.upt(rpos[1],que[1],que[2]);
for(int i=2;i<tail;i++){
node tmp2=tmp;
tmp.upt(rpos[i],&tmp2,que[i+1]);
}
return tmp.sum;
}
inline void modify(node *&now,int l,int r,int pos){
if(l==r){
now->sum=now->mxl=now->mxr=v[0][l];
now->posl=now->posr=l;
now->cntline=1;
return;
}
int mid=(l+r)>>1;
if(pos<=mid)modify(now->lc,l,mid,pos);
else modify(now->rc,mid+1,r,pos);
now->upt(mid,now->lc,now->rc);
}
}ST;
int main(){
io.init();n=io.read(),m=io.read();
for(int i=1;i<n;i++)v[1][i]=io.read();
for(int i=1;i<n;i++)v[2][i]=io.read();
for(int i=1;i<=n;i++)v[0][i]=io.read();
ST.build(ST.rt,1,n);
for(int i=1;i<=m;i++){
static char ch[2];
cin>>(ch+1);
if(ch[1]=='Q'){
int l=io.read(),r=io.read();
io.W(ST.query(l,r));
}
else{
int r1=io.read(),c1=io.read(),r2=io.read(),c2=io.read();
if(r1==r2){
if(c1>c2)swap(c1,c2);
v[r1][c1]=io.read();
ST.modify(ST.rt,1,n,c2);
}
else{
v[0][c1]=io.read();
ST.modify(ST.rt,1,n,c1);
}
}
}
}