这个线段树一眼秒了(主要是有前面的思考经验)
就是维护两个列对应线段上的形态。,比较好想的
但数据结构题有个特点——使你知道结构也不会做————会做也会很大概率爆零....
所以数据结构题必须 小数据+特殊数据 + 对拍!!!!不然怎么挂的都不知道、
敲+错+调+查+调 搞了一个上午
这个题用线段树维护 一个最小值 合并时需要考虑 不同形态 子图(其实是树)的合并方法
但其实只和两个端点有关:
看着丧心病狂的up就知道有多难调了(关键当时还不知道对不对,写完需要胆量)
码:
#include<iostream>
#include<cstdio>
using namespace std;
#define zuo l,mid,o<<1
#define you mid+1,r,o<<1|1
#define N 60006
int IO[N<<2],II[N<<2],lu[4][N],x,xx,y,yy,z,n,m,i,a,b,ans,cha,OI[N<<2],OO[N<<2],deng[N<<2],linOO,linOI,linIO,linII,lindeng,llinIO,llinOI,llinII,llinOO,llindeng;
bool yici;
char op;
void up(int o,int mid)
{
IO[o]=II[o<<1]+lu[1][mid]+lu[2][mid]+OO[o<<1|1]; //II+OO
IO[o]=min(IO[o],II[o<<1]+min(lu[1][mid],lu[2][mid])+IO[o<<1|1]); //II+IO
IO[o]=min(IO[o],II[o<<1]+min(lu[1][mid],lu[2][mid])+deng[o<<1|1]); //II+=
IO[o]=min(IO[o],IO[o<<1]+lu[1][mid]+lu[2][mid]+deng[o<<1|1]); //IO+=
IO[o]=min(IO[o],IO[o<<1]+IO[o<<1|1]+lu[1][mid]+lu[2][mid]); //IO+IO
IO[o]=min(IO[o],deng[o<<1]+lu[1][mid]+lu[2][mid]+IO[o<<1|1]); //=+IO
OI[o]=OI[o<<1]+lu[1][mid]+lu[2][mid]+deng[o<<1|1]; //OI+=
OI[o]=min(OI[o],OI[o<<1]+lu[1][mid]+lu[2][mid]+OI[o<<1|1]); //OI+OI
OI[o]=min(OI[o],OI[o<<1]+min(lu[1][mid],lu[2][mid])+II[o<<1|1]); //OI+II
OI[o]=min(OI[o],OO[o<<1]+II[o<<1|1]+lu[1][mid]+lu[2][mid]); //OO+II
OI[o]=min(OI[o],deng[o<<1]+lu[1][mid]+lu[2][mid]+OI[o<<1|1]); //=+OI
OI[o]=min(OI[o],deng[o<<1]+min(lu[1][mid],lu[2][mid])+II[o<<1|1]); //=+II
II[o]=IO[o<<1]+II[o<<1|1]+lu[1][mid]+lu[2][mid]; //IO+II
II[o]=min(II[o],II[o<<1]+deng[o<<1|1]+lu[1][mid]+lu[2][mid]); //II+=
II[o]=min(II[o],deng[o<<1]+II[o<<1|1]+lu[1][mid]+lu[2][mid]); //=+II
II[o]=min(II[o],II[o<<1]+OI[o<<1|1]+lu[1][mid]+lu[2][mid]); //II+OI
II[o]=min(II[o],II[o<<1]+II[o<<1|1]+min(lu[1][mid],lu[2][mid])); //II+II
OO[o]=deng[o<<1]+deng[o<<1|1]+min(lu[1][mid],lu[2][mid]); //=+=
OO[o]=min(OO[o],deng[o<<1]+OO[o<<1|1]+lu[1][mid]+lu[2][mid]); //=+OO
OO[o]=min(OO[o],deng[o<<1]+IO[o<<1|1]+min(lu[1][mid],lu[2][mid])); //=+IO
OO[o]=min(OO[o],OI[o<<1]+IO[o<<1|1]+min(lu[1][mid],lu[2][mid])); //OI+IO
OO[o]=min(OO[o],OI[o<<1]+OO[o<<1|1]+lu[1][mid]+lu[2][mid]); //OI+OO
OO[o]=min(OO[o],OI[o<<1]+deng[o<<1|1]+min(lu[1][mid],lu[2][mid])); //OI+=
OO[o]=min(OO[o],OO[o<<1]+deng[o<<1|1]+lu[1][mid]+lu[2][mid]); //OO+=
OO[o]=min(OO[o],OO[o<<1]+IO[o<<1|1]+lu[1][mid]+lu[2][mid]); //OO+IO
deng[o]=deng[o<<1]+deng[o<<1|1]+lu[1][mid]+lu[2][mid]; //=+=
}
void jian(int l,int r,int o)
{
int mid=(l+r)>>1;
if(l==r)
{
II[o]=lu[3][l];IO[o]=OI[o]=1e9+7;deng[o]=0;
return;
}
jian(zuo);
jian(you);
up(o,mid);
}
void wen(int l,int r,int o)
{
if(a<=l&&r<=b)
{
if(yici)
{
linOI=OI[o];
linIO=IO[o];
linOO=OO[o];
lindeng=deng[o];
linII=II[o];
yici=0;
}else
{
llinIO=linII+lu[1][l-1]+lu[2][l-1]+OO[o]; //II+OO
llinIO=min(llinIO,linII+min(lu[1][l-1],lu[2][l-1])+IO[o]); //II+IO
llinIO=min(llinIO,linII+min(lu[1][l-1],lu[2][l-1])+deng[o]); //II+=
llinIO=min(llinIO,linIO+lu[1][l-1]+lu[2][l-1]+deng[o]); //IO+=
llinIO=min(llinIO,linIO+IO[o]+lu[1][l-1]+lu[2][l-1]); //IO+IO
llinIO=min(llinIO,lindeng+lu[1][l-1]+lu[2][l-1]+IO[o]); //=+IO
llinOI=linOI+lu[1][l-1]+lu[2][l-1]+deng[o]; //OI+=
llinOI=min(llinOI,linOI+lu[1][l-1]+lu[2][l-1]+OI[o]); //OI+OI
llinOI=min(llinOI,linOI+min(lu[1][l-1],lu[2][l-1])+II[o]); //OI+II
llinOI=min(llinOI,linOO+II[o]+lu[1][l-1]+lu[2][l-1]); //OO+II
llinOI=min(llinOI,lindeng+lu[1][l-1]+lu[2][l-1]+OI[o]); //=+OI
llinOI=min(llinOI,lindeng+min(lu[1][l-1],lu[2][l-1])+II[o]); //=+II
llinII=linIO+II[o]+lu[1][l-1]+lu[2][l-1]; //IO+II
llinII=min(llinII,linII+deng[o]+lu[1][l-1]+lu[2][l-1]); //II+=
llinII=min(llinII,lindeng+II[o]+lu[1][l-1]+lu[2][l-1]); //=+II
llinII=min(llinII,linII+OI[o]+lu[1][l-1]+lu[2][l-1]); //II+OI
llinII=min(llinII,linII+II[o]+min(lu[1][l-1],lu[2][l-1])); //II+II
llinOO=lindeng+deng[o]+min(lu[1][l-1],lu[2][l-1]); //=+=
llinOO=min(llinOO,lindeng+OO[o]+lu[1][l-1]+lu[2][l-1]); //=+OO
llinOO=min(llinOO,lindeng+IO[o]+min(lu[1][l-1],lu[2][l-1])); //=+IO
llinOO=min(llinOO,linOI+IO[o]+min(lu[1][l-1],lu[2][l-1])); //OI+IO
llinOO=min(llinOO,linOI+OO[o]+lu[1][l-1]+lu[2][l-1]); //OI+OO
llinOO=min(llinOO,linOI+deng[o]+min(lu[1][l-1],lu[2][l-1])); //OI+=
llinOO=min(llinOO,linOO+deng[o]+lu[1][l-1]+lu[2][l-1]); //OO+=
llinOO=min(llinOO,linOO+IO[o]+lu[1][l-1]+lu[2][l-1]); //OO+IO
llindeng=lindeng+deng[o]+lu[1][l-1]+lu[2][l-1];
linOO=llinOO;
linII=llinII;
linOI=llinOI;
linIO=llinIO;
lindeng=llindeng;
}
return ;
}
int mid=(l+r)>>1;
if(a<=mid)wen(zuo);
if(b>mid)wen(you);
}
void gai(int l,int r,int o)
{
int mid=(l+r)>>1;
if(l==r)
{
II[o]=lu[3][l];IO[o]=OI[o]=1e9+7;
deng[o]=0;
return;
}
if(a<=mid)gai(zuo);
else gai(you);
up(o,mid);
}
int main()
{
scanf("%d%d",&n,&m);
for(i=1;i<n;i++)scanf("%d",&lu[1][i]);
for(i=1;i<n;i++)scanf("%d",&lu[2][i]);
for(i=1;i<=n;i++)scanf("%d",&lu[3][i]);
jian(1,n,1);
for(i=1;i<=m;i++)
{
scanf("%c",&op);while(op!='Q'&&op!='C')scanf("%c",&op);
if(op=='Q')
{
scanf("%d%d",&a,&b);
yici=1;
wen(1,n,1);
printf("%d\n",linII);
}else
{
scanf("%d%d%d%d%d",&x,&y,&xx,&yy,&z);
if(yy<y)swap(y,yy);
if(x==xx&&x==1)lu[1][y]=z;
if(x==xx&&x==2)lu[2][y]=z;
if(x!=xx)lu[3][y]=z;
a=y;
gai(1,n,1);
}
}
}