码迷,mamicode.com
首页 > 其他好文 > 详细

HDU3397Sequence operation

时间:2014-09-03 13:08:46      阅读:237      评论:0      收藏:0      [点我收藏+]

标签:blog   os   io   2014   sp   log   html   amp   on   

这题写着真累,⊙﹏⊙b汗

各种操作,具体见注释


#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <climits>
#include <string>
#include <iostream>
#include <map>
#include <cstdlib>
#include <list>
#include <set>
#include <queue>
#include <stack>
using namespace std;
#define INF 0xfffffff
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define maxn 100010
int unsum[maxn<<2],sum[maxn<<2],lsum[maxn<<2],rsum[maxn<<2],zsum[maxn<<2],lzsum[maxn<<2],rzsum[maxn<<2],col[maxn<<2];
//unsum存储1的个数,sum存储连续的1,zsun存储连续的0
void pushup(int rt,int m)//向上更新
{
    unsum[rt]=unsum[rt<<1]+unsum[rt<<1|1];
    lsum[rt]=lsum[rt<<1];
    rsum[rt]=rsum[rt<<1|1];
    if(lsum[rt]==(m-(m>>1))) lsum[rt]+=lsum[rt<<1|1];
    if(rsum[rt]==(m>>1)) rsum[rt]+=rsum[rt<<1];
    sum[rt]=max(max(sum[rt<<1],sum[rt<<1|1]),rsum[rt<<1]+lsum[rt<<1|1]);
    lzsum[rt]=lzsum[rt<<1];
    rzsum[rt]=rzsum[rt<<1|1];
    if(lzsum[rt]==(m-(m>>1))) lzsum[rt]+=lzsum[rt<<1|1];
    if(rzsum[rt]==(m>>1)) rzsum[rt]+=rzsum[rt<<1];
    zsum[rt]=max(max(zsum[rt<<1],zsum[rt<<1|1]),rzsum[rt<<1]+lzsum[rt<<1|1]);
}
void SWAP(int rt,int m)//交换操作,似的区间内0和1交换
{
    col[rt]=1-col[rt];
    unsum[rt]=m-unsum[rt];
    swap(sum[rt],zsum[rt]);
    swap(lsum[rt],lzsum[rt]);
    swap(rsum[rt],rzsum[rt]);
}
void pushdown(int rt,int m)//向下更新
{
    if(col[rt]==2)
    {
        col[rt]=-1;
        SWAP(rt<<1,m-(m>>1));
        SWAP(rt<<1|1,m>>1);
    }
    if(col[rt]!=-1)
    {
        col[rt<<1]=col[rt<<1|1]=col[rt];
        unsum[rt<<1]=sum[rt<<1]=lsum[rt<<1]=rsum[rt<<1]=col[rt<<1]?(m-(m>>1)):0;
        unsum[rt<<1|1]=sum[rt<<1|1]=lsum[rt<<1|1]=rsum[rt<<1|1]=col[rt<<1|1]?(m>>1):0;
        zsum[rt<<1]=lzsum[rt<<1]=rzsum[rt<<1]=col[rt<<1]?0:(m-(m>>1));
        zsum[rt<<1|1]=lzsum[rt<<1|1]=rzsum[rt<<1|1]=col[rt<<1|1]?0:(m>>1);
        col[rt]=-1;
    }
}
void build(int l,int r,int rt)
{
    col[rt]=-1;
    if(l==r)
    {
        scanf("%d",&sum[rt]);
        unsum[rt]=lsum[rt]=rsum[rt]=sum[rt];
        zsum[rt]=lzsum[rt]=rzsum[rt]=sum[rt]^1;
        return ;
    }
    int m=(l+r)>>1;
    build(lson);
    build(rson);
    pushup(rt,r-l+1);
}
void update(int L,int R,int add,int l,int r,int rt)
{
    if(L<=l&&R>=r)
    {
        if(add==2)
        {
            SWAP(rt,r-l+1);
        }
        else
        {
            col[rt]=add;
            unsum[rt]=sum[rt]=lsum[rt]=rsum[rt]=add?r-l+1:0;
            zsum[rt]=lzsum[rt]=rzsum[rt]=add?0:r-l+1;
        }
        return ;
    }
    pushdown(rt,r-l+1);
    int m=(l+r)>>1;
    if(L<=m) update(L,R,add,lson);
    if(R>m) update(L,R,add,rson);
    pushup(rt,r-l+1);
}
int query(int L,int R,int add,int l,int r,int rt)//查询操作
{
    int ans=0,m=(l+r)>>1;
    if(add==3)
    {
        if(L<=l&&R>=r)
        {
            return unsum[rt];
        }
        pushdown(rt,r-l+1);
        if(L<=m) ans+=query(L,R,add,lson);
        if(R>m) ans+=query(L,R,add,rson);
        return ans;
    }
    if(L<=l&&R>=r)
    {
        return sum[rt];
    }
    pushdown(rt,r-l+1);
    ans=min(m-L+1,rsum[rt<<1])+min(lsum[rt<<1|1],R-m);
    if(L<=m) ans=max(ans,query(L,R,add,lson));
    if(R>m) ans=max(ans,query(L,R,add,rson));
    return ans;
}
int main()
{
    int t;
    int n,m;
    int a,b,op;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        build(1,n,1);
        while(m--)
        {
            scanf("%d%d%d",&op,&a,&b);
            if(op<3)
            {
                update(a+1,b+1,op,1,n,1);
            }
            else
            {
                printf("%d\n",query(a+1,b+1,op,1,n,1));
            }
        }
    }
    return 0;
}


HDU3397Sequence operation

标签:blog   os   io   2014   sp   log   html   amp   on   

原文地址:http://blog.csdn.net/u013748887/article/details/39025623

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!