HDU 3397 Sequence operation (線段樹,成段更新,區間合并)

來源:互聯網
上載者:User

標籤:線段樹   成段更新   區間合并   algorithm   資料結構   

http://acm.hdu.edu.cn/showproblem.php?pid=3397

Sequence operation Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5801    Accepted Submission(s): 1713


Problem Descriptionlxhgww got a sequence contains n characters which are all ‘0‘s or ‘1‘s.
We have five operations here:
Change operations:
0 a b change all characters into ‘0‘s in [a , b]
1 a b change all characters into ‘1‘s in [a , b]
2 a b change all ‘0‘s into ‘1‘s and change all ‘1‘s into ‘0‘s in [a, b]
Output operations:
3 a b output the number of ‘1‘s in [a, b]
4 a b output the length of the longest continuous ‘1‘ string in [a , b] 
InputT(T<=10) in the first line is the case number.
Each case has two integers in the first line: n and m (1 <= n , m <= 100000).
The next line contains n characters, ‘0‘ or ‘1‘ separated by spaces.
Then m lines are the operations:
op a b: 0 <= op <= 4 , 0 <= a <= b < n. 
OutputFor each output operation , output the result. 
Sample Input
110 100 0 0 1 1 0 1 0 1 11 0 23 0 52 2 24 0 40 3 62 3 74 2 81 0 50 5 63 3 9
 
Sample Output
5265
 
Authorlxhgww&&shǎ崽 
SourceHDOJ Monthly Contest – 2010.05.01 

表示再也不想看到線段樹了>_<

題意:

0 a b:將區間[a,b]全部置為0;

1 a b:將區間[a,b]全部置為1;

2 a b:對區間[a,b]進行異或操作;

3 a b:詢問區間[a,b]內有多少個1;

4 a b:詢問區間[a,b]內最長連續的1有多長。

分析:

置0/1很簡單成段更新lazy一下就行了,詢問有多少個1就是個求和,維護區間內和值即可。詢問最長連續的1是個區間合并,我們要維護3個值,區間左頂點開始的最長連續1,右頂點開始的最長聯絡1,區間內的最長連續1,這樣維護父節點的時候要注意他的左右孩子是否連續。

異或操作就比較複雜,我們不僅要維護1的資訊,還要維護0的資訊。如果該區間內的值相同(setv!=-1),那麼setv^=1並且交換0/1資訊的值,否則XOR^=1並且交換0/1資訊的值。pushdown有些麻煩,如果setv[k]!=-1(k是當前節點,lc是左孩子,rc是右孩子),那麼他兩個孩子之前的異或操作都會被覆蓋掉,所以下傳setv[k],並將兩個孩子的XOR標記清空;如果XOR[k]==1,那麼將兩個孩子自身的0/1資訊互換並將XOR下傳給左右孩子。


#include<cstdio>#include<iostream>#include<cstdlib>#include<algorithm>#include<ctime>#include<cctype>#include<cmath>#include<string>#include<cstring>#include<stack>#include<queue>#include<list>#include<vector>#include<map>#include<set>#define sqr(x) ((x)*(x))#define LL long long#define itn int#define INF 0x3f3f3f3f#define PI 3.1415926535897932384626#define eps 1e-10#define maxm#define maxn 100007using namespace std;int XOR[maxn<<2],setv[maxn<<2],lm1[maxn<<2],rm1[maxn<<2],lm0[maxn<<2],rm0[maxn<<2],sum[maxn<<2],msum1[maxn<<2],msum0[maxn<<2];inline void SWAP(int k,int l,int r){    swap(lm1[k],lm0[k]);swap(rm1[k],rm0[k]);swap(msum1[k],msum0[k]);sum[k]=r-l-sum[k];}inline void pushup(int k,int l,int r){    int lc=k*2+1,rc=k*2+2,m=l+r>>1;    sum[k]=sum[lc]+sum[rc];    if (lm1[lc]==m-l)   lm1[k]=lm1[lc]+lm1[rc]; else    lm1[k]=lm1[lc];    if (rm1[rc]==r-m)   rm1[k]=rm1[rc]+rm1[lc]; else    rm1[k]=rm1[rc];    msum1[k]=max(rm1[lc]+lm1[rc],max(msum1[lc],msum1[rc]));    if (lm0[lc]==m-l)   lm0[k]=lm0[lc]+lm0[rc]; else    lm0[k]=lm0[lc];    if (rm0[rc]==r-m)   rm0[k]=rm0[rc]+rm0[lc]; else    rm0[k]=rm0[rc];    msum0[k]=max(rm0[lc]+lm0[rc],max(msum0[lc],msum0[rc]));}inline void pushdown(int k,int l,int r){    int lc=k*2+1,rc=k*2+2,m=l+r>>1;    if (setv[k]!=-1)    {        setv[lc]=setv[rc]=setv[k];        XOR[lc]=XOR[rc]=0;        lm1[lc]=rm1[lc]=msum1[lc]=sum[lc]=setv[k]?m-l:0;        lm0[lc]=rm0[lc]=msum0[lc]=setv[k]?0:m-l;        lm1[rc]=rm1[rc]=msum1[rc]=sum[rc]=setv[k]?r-m:0;        lm0[rc]=rm0[rc]=msum0[rc]=setv[k]?0:r-m;        setv[k]=-1;    }    if (XOR[k])    {        if (setv[lc]!=-1)   setv[lc]^=1;    else    XOR[lc]^=1;        if (setv[rc]!=-1)   setv[rc]^=1;    else    XOR[rc]^=1;        SWAP(lc,l,m);SWAP(rc,m,r);        XOR[k]=0;    }}void update(int a,int b,int v,int k,int l,int r){    if (b<=l || r<=a)   return ;    if (a<=l && r<=b)    {        setv[k]=v;        lm1[k]=rm1[k]=msum1[k]=sum[k]=v?r-l:0;        lm0[k]=rm0[k]=msum0[k]=v?0:r-l;        XOR[k]=0;    }    else    {        pushdown(k,l,r);        int m=l+r>>1;        update(a,b,v,k*2+1,l,m);        update(a,b,v,k*2+2,m,r);        pushup(k,l,r);    }}void change(int a,int b,int k,int l,int r){    if (b<=l || r<=a)   return ;    if (a<=l && r<=b)    {        if (setv[k]!=-1)            setv[k]^=1;        else            XOR[k]^=1;        SWAP(k,l,r);    }    else    {        pushdown(k,l,r);        int m=l+r>>1;        change(a,b,k*2+1,l,m);        change(a,b,k*2+2,m,r);        pushup(k,l,r);    }}int query_sum(int a,int b,int k,int l,int r){    if (b<=l || r<=a)   return 0;    if (a<=l && r<=b) return sum[k];    if (r-l!=1) pushdown(k,l,r);    int m=l+r>>1,v1=0,v2=0;    v1=query_sum(a,b,k*2+1,l,m);    v2=query_sum(a,b,k*2+2,m,r);    return v1+v2;}int query_lc1(itn a,int b,int k,int l,int r){    if (b<=l || r<=a)   return 0;    if (a<=l && r<=b)   return msum1[k];    if (r-l!=1) pushdown(k,l,r);    int m=l+r>>1,v1=0,v2=0,v3=0;    v1=query_lc1(a,b,k*2+1,l,m);    v2=query_lc1(a,b,k*2+2,m,r);    v3=min(b,m+lm1[k*2+2])-max(a,m-rm1[k*2+1]);    return max(v3,max(v1,v2));}int main(){    #ifndef ONLINE_JUDGE        freopen("/home/fcbruce/文檔/code/t","r",stdin);    #endif // ONLINE_JUDGE    int T_T,n,m,x,a,b,op;    scanf("%d",&T_T);    while (T_T--)    {        scanf("%d %d",&n,&m);        for (int i=0;i<n;i++)        {            scanf("%d",&x);            update(i,i+1,x,0,0,n);        }        while (m--)        {            scanf("%d %d %d",&op,&a,&b);            if (op==0)            {                update(a,b+1,0,0,0,n);                continue;            }            if (op==1)            {                update(a,b+1,1,0,0,n);                continue;            }            if (op==2)            {                change(a,b+1,0,0,n);                continue;            }            if (op==3)            {                printf("%d\n",query_sum(a,b+1,0,0,n));                continue;            }            if (op==4)            {                printf("%d\n",query_lc1(a,b+1,0,0,n));                continue;            }        }    }    return 0;}


HDU 3397 Sequence operation (線段樹,成段更新,區間合并)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.