题意:定义一个序列的权值为里面的最长的子线段满足线段内的数一样
给出一个序列,每次给出其子区间l,r作为序列,你可以至多执行k次操作,使得操作后序列的权值最大,输出最大权值。其中,一次操作选定
p
p
p,
r
e
v
(
l
,
p
)
,
r
e
v
(
p
+
1
,
r
)
rev(l,p),rev(p+1,r)
rev(l,p),rev(p+1,r)
解法:这是一道本蒟蒻永远无法做出来的神题。
翻转三次及其以上是无任何意义的
于是一棵线段树维护一下相关信息即可
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m;
#define Maxn 200010
int a[Maxn];
int tag[Maxn<<2];
struct Data{
int ans;
int lval,lans;
int rval,rans;
int len;
}tree[Maxn<<2];
Data merge(Data a,Data b){
Data res;
res.len=a.len+b.len;
res.lval=a.lval;
if(a.lans==a.len&&b.lval==a.lval)res.lans=a.lans+b.lans;
else res.lans=a.lans;
res.rval=b.rval;
if(b.rans==b.len&&a.rval==b.rval)res.rans=a.rans+b.rans;
else res.rans=b.rans;
res.ans=max(a.ans,b.ans);
if(a.rval==b.lval)res.ans=max(res.ans,a.rans+b.lans);
return res;
}
void push_up(int k){tree[k]=merge(tree[k<<1],tree[k<<1|1]);}
inline void Maketag(int k,int val){
tag[k]=val;
tree[k].ans=tree[k].lans=tree[k].rans=tree[k].len;
tree[k].lval=tree[k].rval=val;
}
void push_down(int k){
if(tag[k]){
Maketag(k<<1,tag[k]);
Maketag(k<<1|1,tag[k]);
tag[k]=0;
}
}
void Build_Tree(int k,int l,int r){
if(l==r){
tree[k].ans=tree[k].lans=tree[k].rans=tree[k].len=1;
tree[k].lval=tree[k].rval=a[l];
return;
}
int mid=(l+r)>>1;
Build_Tree(k<<1,l,mid);
Build_Tree(k<<1|1,mid+1,r);
push_up(k);
}
void Modify(int k,int l,int r,int L,int R,int val){
if(l==L&&r==R){
Maketag(k,val);
return;
}
push_down(k);
int mid=(l+r)>>1;
if(R<=mid)Modify(k<<1,l,mid,L,R,val);
else if(mid<L)Modify(k<<1|1,mid+1,r,L,R,val);
else{
Modify(k<<1,l,mid,L,mid,val);
Modify(k<<1|1,mid+1,r,mid+1,R,val);
}
push_up(k);
}
Data Query(int k,int l,int r,int L,int R){
if(l==L&&r==R)return tree[k];
push_down(k);
int mid=(l+r)>>1;
if(R<=mid)return Query(k<<1,l,mid,L,R);
else if(mid<L)return Query(k<<1|1,mid+1,r,L,R);
else return merge(Query(k<<1,l,mid,L,mid),Query(k<<1|1,mid+1,r,mid+1,R));
}
inline void rd(int &x){
x=0;char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
}
char opt[5];
int main(){
rd(n);rd(m);
for(register int i=1;i<=n;++i)rd(a[i]);
Build_Tree(1,1,n);
int l,r,x,k;
for(register int tt=1;tt<=m;++tt){
scanf("%s",opt);
if(opt[0]=='R'){
rd(l);rd(r);rd(x);
Modify(1,1,n,l,r,x);
}else{
rd(l);rd(r);rd(k);
Data res=Query(1,1,n,l,r);
if(!k)printf("%d\n",res.ans);
else{
int Ans=res.ans;
if(Ans==r-l+1)printf("%d\n",Ans);
else{
if(res.lval==res.rval)Ans=max(Ans,res.lans+res.rans);
printf("%d\n",Ans);
}
}
}
}
return 0;
}