1. 程式人生 > >DTOJ 1015: 幸運字串查詢 (lucky)

DTOJ 1015: 幸運字串查詢 (lucky)

1015: 幸運字串查詢 (lucky)
時間限制: 2 S e c 2 Sec 記憶體限制: 256 M

B 256 MB O 2 O2
題目描述
K C
KC
研究完了幸運數列,又開始對幸運字串感興趣( K C KC 似乎不是個正常人)。幸運字串是一個只包括
4 '4'
7 '7' 的字串。現在 K C KC 手中有個長度為 N ( 1 N 1 , 000 , 000 ) N(1\leq N \leq 1,000,000) 的幸運字串。天生調皮愛玩的 K C KC 開始玩起了這個字串,他的玩法是每次從這個字串中選定一段區間 [ l , r ] [l,r] ,將這段區間上的所有 4 '4' 換成 7 '7' ,所有 7 '7' 換成 4 '4'
但是 K C KC 過了很久終於意識到自己玩的東西太無聊了,於是他找來你陪他玩,他會在變換玩若干區間後突然問你一個問題:當前這個幸運字串的最長不降子序列的長度是多少?
現在給出 N N M M ,以及KC手中原有的幸運字串,M為KC自己玩的次數加上詢問你的次數,還有M次的資訊。
輸入
第一行包括 N , M N,M , M 300 000 M\leq 300,000 .
第二行是一個長度為 N N 的幸運字串。
接下來 M M 行,每行一個操作資訊,遊戲中會按照給定的順序執行操作。。
s w i t c h switch l l r r 表示 K C KC 對區間 [ l , r ] [l,r] 進行了變換。
c o u n t count 表示 K C KC 向你提問了,你必須輸出你的答案。

輸出
每行對應一個 c o u n t count

樣例輸入
2 3
47
count
switch 1 2
count
樣例輸出
2
1
提示
【樣例輸入2】
3 5
747
count
switch 1 1
count
switch 1 3
count
【樣例輸出2】
2
3
2
【資料範圍】
對於 30 % 30\% 的資料 n , m 1000 n,m\leq 1000

題解

一道線段樹騷題。(退役前最後掙扎

由於它只有 4 , 7 4,7 兩個數字,所以可以得到有兩種情況:
1 1 : 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 4,4,4,4,4,4,4,4,4
2 2 : 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 7,7,7,7,7,7,7,7,7
3 3 : 4 , 4 , 4 , 4 , 7 , 7 , 7 , 7 , 7 4,4,4,4,7,7,7,7,7

所以我們考慮存下這三種情況。由於有修改,考慮線段樹。
所以我們線上段樹裡存下這三種情況。
由於他帶了翻轉,所以再多記一個: 7 , 7 , 7 , 7 , 4 , 4 , 4 , 4 7,7,7,7,4,4,4,4 的情況,翻轉時直接將這幾種情況交換。

#include<bits/stdc++.h>
using namespace std;
#define in inline
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define _(d) while(d(isdigit(ch=getchar())))
in void g(int &t) {int x,f=1;char ch;_(!)ch=='-'?f=-1:f;x=ch-48;_()x=x*10+ch-48;t=f*x;}
const int N=1e6+4;
char str[N],op[10];
struct seg{
    int l,r,_7,_4,_47,_74;bool f; 
}t[N<<2];
int n,m; 
in void up(int x){
    t[x]._4=t[x<<1]._4+t[x<<1|1]._4;
    t[x]._7=t[x<<1]._7+t[x<<1|1]._7;
    t[x]._47=max(t[x<<1]._4+t[x<<1|1]._7,max(t[x<<1]._4+t[x<<1|1]._47,t[x<<1]._47+t[x<<1|1]._7));
    t[x]._74=max(t[x<<1]._7+t[x<<1|1]._4,max(t[x<<1]._7+t[x<<1|1]._74,t[x<<1]._74+t[x<<1|1]._4)); 
} 
in void gao(int x){swap(t[x]._4,t[x]._7);swap(t[x]._47,t[x]._74);}
in void pd(int x){
    if(t[x].f){
        if(t[x].l!=t[x].r) t[x<<1].f^=1,t[x<<1|1].f^=1;
        gao(x<<1);gao(x<<1|1);
        t[x].f=0;
    }
}
in void build(int x,int l,int r){
    t[x].l=l,t[x].r=r;
    if(l==r){
        if(str[l]=='4') t[x]._4=1;
        else t[x]._7=1;return;
    }
    int mid=l+r>>1;
    build(x<<1,l,mid);build(x<<1|1,mid+1,r); 
    up(x);
}
in void Re(int x,int L,int R){
    pd(x);
    if(t[x].l>=L&&t[x].r<=R){t[x].f^=1;gao(x);return;}
    int mid=t[x].l+t[x].r>>1;
    if(L<=mid) Re(x<<1,L,R);
    if(mid<R) Re(x<<1|1,L,R);
    up(x); 
}
int main(){
    g(n);g(m);scanf("%s",str+1);
    build(1,1,n);
    rep(i,1,m){
        scanf("%s",op);
        if(op[0]=='c') printf("%d\n",max(max(t[1]._47,t[1]._4),t[1]._7));
        if(op[0]=='s'){int L,R;g(L),g(R);Re(1,L,R);}
    }
    return 0;
}