题目描述
KC研究完了幸运数列,又开始对幸运字符串感兴趣(KC似乎不是个正常人)。幸运字符串是一个只包括 ‘4’ 和 ‘7’ 的字符串。现在KC手中有个长度为 N(1≤N≤106)N(1\le N\le 10^6)N(1≤N≤106) 的幸运字符串。天生调皮爱玩的KC开始玩起了这个字符串,他的玩法是每次从这个字符串中选定一段区间 [l,r][l,r][l,r] ,将这段区间上的所有 ‘4’ 换成 ‘7’,所有 ‘7’ 换成 ‘4’ 。
但是KC过了很久终于意识到自己玩的东西太无聊了,于是他找来你陪他玩,他会在变换玩若干区间后突然问你一个问题:当前这个幸运字符串的最长不降子序列的长度是多少?
现在给出 NNN 和 MMM ,以及KC手中原有的幸运字符串,MMM 为KC自己玩的次数加上询问你的次数,还有 MMM 次的信息。
输入格式
第一行包括 N,M(M≤300000)N,M(M\le 300000)N,M(M≤300000) 。
第二行是一个长度为 NNN 的幸运字符串。
接下来 MMM 行,每行一个操作信息,游戏中会按照给定的顺序执行操作。
switch l r表示KC对区间 [l,r][l,r][l,r] 进行了变换。
count表示KC向你提问了,你必须输出你的答案。
输出格式
每行对应一个count。
样例
样例输入 1
2 3
47
count
switch 1 2
count
样例输出 1
2
1
样例输入 2
3 5
747
count
switch 1 1
count
switch 1 3
count
样例输出 2
2
3
2
数据范围与提示
对于 30%30%30% 的数据 n,m≤1000n,m\le 1000n,m≤1000 。
题解:
因为只有两个字符,所以不减子序列只可能是4444444或4444477777或7777777
但题目又要支持反转,所以
4444444—>77777777
4444447777777—>777777774444444
7777777—>44444444
由此看来,还得记录一个77777777444444444
而答案就是前三个的最大值,
所以数据结构就呼之欲出了:
线段树!
#include
#include
#include
#include
#include
#define N 1000005
using namespace std;
int n,m,a[N];
struct segement
{
int l,r,f1,f2,f3,f4;
int lazy;
}t[N*4];//f1 4444 f2 444777 f3 777777 f4 7777744444
void build(int p,int l,int r){
t[p].l=l;t[p].r=r;
if(l==r){
if(a[l]==4){
t[p].f1++;
}else{
t[p].f3++;
}
return ;
}
int mid=(l+r)>>1;
build(p*2,l,mid);build(p*2+1,mid+1,r);
t[p].f2=max(max(t[p*2].f2,t[p*2].f1+t[p*2+1].f2),max(t[p*2+1].f2,t[p*2].f1+t[p*2+1].f3));
t[p].f2=max(t[p].f2,t[p*2].f2+t[p*2+1].f3);
t[p].f1=max(t[p*2].f1,max(t[p*2+1].f1,t[p*2].f1+t[p*2+1].f1));
t[p].f3=max(t[p*2].f3,max(t[p*2+1].f3,t[p*2].f3+t[p*2+1].f3));
t[p].f4=max(max(t[p*2].f4,t[p*2].f3+t[p*2+1].f4),max(t[p*2+1].f4,t[p*2].f3+t[p*2+1].f1));
t[p].f4=max(t[p].f4,t[p*2].f4+t[p*2+1].f1);
}
void spread(int p){
if(t[p].lazy&1){
swap(t[p*2].f1,t[p*2].f3);
swap(t[p*2].f2,t[p*2].f4);
swap(t[p*2+1].f1,t[p*2+1].f3);
swap(t[p*2+1].f2,t[p*2+1].f4);
t[p*2].lazy+=t[p].lazy;
t[p*2+1].lazy+=t[p].lazy;
t[p].lazy=0;
}
}
//f1 4444 f2 444777 f3 777777 f4 7777744444
void change(int p,int l,int r){
if(t[p].l>=l&&t[p].r<=r){
swap(t[p].f1,t[p].f3);
swap(t[p].f2,t[p].f4);
t[p].lazy+=1;
return ;
}
spread(p);
int mid=(t[p].l+t[p].r)>>1;
if(l<=mid)change(p*2,l,r);
if(r>mid)change(p*2+1,l,r);
t[p].f2=max(max(t[p*2].f2,t[p*2].f1+t[p*2+1].f2),max(t[p*2+1].f2,t[p*2].f1+t[p*2+1].f3));
t[p].f2=max(t[p].f2,t[p*2].f2+t[p*2+1].f3);
t[p].f1=max(t[p*2].f1,max(t[p*2+1].f1,t[p*2].f1+t[p*2+1].f1));
t[p].f3=max(t[p*2].f3,max(t[p*2+1].f3,t[p*2].f3+t[p*2+1].f3));
t[p].f4=max(max(t[p*2].f4,t[p*2].f3+t[p*2+1].f4),max(t[p*2+1].f4,t[p*2].f3+t[p*2+1].f1));
t[p].f4=max(t[p].f4,t[p*2].f4+t[p*2+1].f1);
}
int main()
{
cin>>n>>m;
string aa;
cin>>aa;
for(int i=1;i<=n;i++){
if(aa[i-1]=='4')a[i]=4;
else a[i]=7;
}
build(1,1,n);
/*for(int i=1;i<=10;i++){
cout<
for(int i=1;i<=m;i++){
cin>>aa;
if(aa[0]=='s'){
int x,y;cin>>x>>y;
change(1,x,y);
}else{
cout<<max(t[1].f1,max(t[1].f2,t[1].f3))<<endl;
}
}
return 0;
}