HDU 3397 Sequence operation 线段树 成段更新 区间合并

比较综合的题。

两个标记  setv,xorr。setv的优先级高于xorr,当一个节点获得一个setv时,他之前的xorr要清除。

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<sstream>
#include<cmath>
#include<climits>
#include<string>
#include<map>
#include<queue>
#include<vector>
#include<stack>
#include<set>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define pb(a) push_back(a)
#define INF 0x1f1f1f1f
#define lson idx<<1,l,mid
#define rson idx<<1|1,mid+1,r
#define PI  3.1415926535898
template<class T> T min(const T& a,const T& b,const T& c) {
    return min(min(a,b),min(a,c));
}
template<class T> T max(const T& a,const T& b,const T& c) {
    return max(max(a,b),max(a,c));
}
void debug() {
#ifdef ONLINE_JUDGE
#else

    freopen("d:\in.txt","r",stdin);
    freopen("d:\out1.txt","w",stdout);
#endif
}
int getch() {
    int ch;
    while((ch=getchar())!=EOF) {
        if(ch!=' '&&ch!='
')return ch;
    }
    return EOF;
}
const int maxn=100100;
struct  node
{
    int num,lc[2],pre[2],suf[2],len;
};
int xorr[maxn<<2];
int setv[maxn<<2];
node tree[maxn<<2];
void Merge(node &q,node &a,node &b)
{
    q.num=a.num+b.num;
    q.len=a.len+b.len;
    for(int i=0;i<2;i++)
    {
        q.lc[i]=max(a.lc[i],b.lc[i],a.suf[i]+b.pre[i]);
        q.pre[i]=a.pre[i]==a.len?a.pre[i]+b.pre[i]:a.pre[i];
        q.suf[i]=b.suf[i]==b.len?b.suf[i]+a.suf[i]:b.suf[i];
    }
}
void PushDown(int idx)
{
    if(setv[idx]!=-1)
    {
        int &v=setv[idx];
        int ls=idx<<1,rs=idx<<1|1;
        setv[ls]=setv[rs]=v;
        xorr[ls]=xorr[rs]=0;

        //lson
        tree[ls].lc[v]=tree[ls].pre[v]=tree[ls].suf[v]=tree[ls].len;
        tree[ls].lc[!v]=tree[ls].pre[!v]=tree[ls].suf[!v]=0;
        tree[ls].num=v==1?tree[ls].len:0;

        //rson
        tree[rs].lc[v]=tree[rs].pre[v]=tree[rs].suf[v]=tree[rs].len;
        tree[rs].lc[!v]=tree[rs].pre[!v]=tree[rs].suf[!v]=0;
        tree[rs].num=v==1?tree[rs].len:0;

        v=-1;
    }
    if(xorr[idx]!=0)
    {
        //lson
        xorr[idx<<1]^=1;
        tree[idx<<1].num=tree[idx<<1].len-tree[idx<<1].num;
        swap(tree[idx<<1].lc[0],tree[idx<<1].lc[1]);
        swap(tree[idx<<1].pre[0],tree[idx<<1].pre[1]);
        swap(tree[idx<<1].suf[0],tree[idx<<1].suf[1]);
        // rson
        xorr[idx<<1|1]^=1;
        tree[idx<<1|1].num=tree[idx<<1|1].len-tree[idx<<1|1].num;
        swap(tree[idx<<1|1].lc[0],tree[idx<<1|1].lc[1]);
        swap(tree[idx<<1|1].pre[0],tree[idx<<1|1].pre[1]);
        swap(tree[idx<<1|1].suf[0],tree[idx<<1|1].suf[1]);

        xorr[idx]=0;
    }
}
int build(int idx,int l,int r)
{
    xorr[idx]=0;
    setv[idx]=-1;
    if(l==r)
    {
        int v;
        scanf("%d",&v);
        tree[idx].len=1;
        tree[idx].num=v==1?1:0;
        tree[idx].lc[v]=tree[idx].pre[v]=tree[idx].suf[v]=1;
        tree[idx].lc[!v]=tree[idx].pre[!v]=tree[idx].suf[!v]=0;
        return 0;
    }
    int mid=(r+l)>>1;
    build(lson);
    build(rson);
    Merge(tree[idx],tree[idx<<1],tree[idx<<1|1]);
    return 0;
}
int update(int idx,int l,int r,int tl,int tr,int op)
{
    if(tl<=l&&tr>=r)
    {
        if(op==2)
        {
            xorr[idx]^=1;
            tree[idx].num=tree[idx].len-tree[idx].num;
            swap(tree[idx].lc[0],tree[idx].lc[1]);
            swap(tree[idx].pre[0],tree[idx].pre[1]);
            swap(tree[idx].suf[0],tree[idx].suf[1]);
        }else
        {
            xorr[idx]=0;
            setv[idx]=op;
            tree[idx].num=op==1?tree[idx].len:0;
            tree[idx].lc[op]=tree[idx].pre[op]=tree[idx].suf[op]=tree[idx].len;
            tree[idx].lc[!op]=tree[idx].pre[!op]=tree[idx].suf[!op]=0;
        }
        return 0;
    }
    PushDown(idx);
    int mid=(r+l)>>1;
    if(tl<=mid)update(lson,tl,tr,op);
    if(tr>mid)update(rson,tl,tr,op);
    Merge(tree[idx],tree[idx<<1],tree[idx<<1|1]);
    return 0;
}
node query(int idx,int l,int r,int tl,int tr)
{
    if(tl<=l&&tr>=r)return tree[idx];
    PushDown(idx);
    int mid=(r+l)>>1;
    node q;
    if(tl<=mid&&tr>mid)
    {
        node a=query(lson,tl,tr);
        node b=query(rson,tl,tr);
        Merge(q,a,b);
    }else if(tl<=mid)q=query(lson,tl,tr);
    else q=query(rson,tl,tr);
    return q;
}
int main()
{
    int t;
    scanf("%d",&t);
    for(int ca=1;ca<=t;ca++)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        build(1,0,n-1);
        for(int i=1;i<=m;i++)
        {
            int op,a,b;
            scanf("%d%d%d",&op,&a,&b);
            if(op<=2)update(1,0,n-1,a,b,op);
            else
            {
                node q=query(1,0,n-1,a,b);
                printf("%d
",op==3?q.num:q.lc[1]);
            }
        }
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/BMan/p/3297044.html