您的位置:首页 > 其它

1858: [Scoi2010]序列操作 线段树

2016-03-15 16:48 369 查看
卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽卧槽

if (l[k]==x&&r[k]==y) 写成了 if(l[k]==r[k]) 。。。。

线段树1s变O(n2)O(n^2)。。。

线段树维护一坨信息。。没了。。

[code]#include<iostream>
#include<cstdio>
#define N 400005
using namespace std;
int n,m,top,cnt;
int l
,r
,l0
,r0
,l1
,r1
,sum0
,sum1
,mx0
,mx1
,size
,tag
;
int a[N>>2],stack[N>>2];
inline int read()
{
    int a=0,f=1; char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
    while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
    return a*f;
}
inline void pushup(int k)
{
    int L=k<<1,R=k<<1|1;
    l0[k]=l0[L]; r0[k]=r0[R];
    l1[k]=l1[L]; r1[k]=r1[R];
    if (l0[L]==size[L]) l0[k]+=l0[R];
    if (l1[L]==size[L]) l1[k]+=l1[R];
    if (r0[R]==size[R]) r0[k]+=r0[L];
    if (r1[R]==size[R]) r1[k]+=r1[L];
    sum0[k]=sum0[L]+sum0[R];
    sum1[k]=sum1[L]+sum1[R];
    mx0[k]=max(r0[L]+l0[R],max(mx0[L],mx0[R]));
    mx1[k]=max(r1[L]+l1[R],max(mx1[L],mx1[R])); 
}
inline void pushdown(int k)
{
    if (l[k]==r[k]) return;
    cnt++;
    int L=k<<1,R=k<<1|1;
    if (tag[k]!=-1)
    {
        int tmp=tag[k];
        tag[k]=-1;
        if (tmp==0)
        {
            l0[L]=r0[L]=mx0[L]=sum0[L]=size[L];
            l1[L]=r1[L]=mx1[L]=sum1[L]=0;
            l0[R]=r0[R]=mx0[R]=sum0[R]=size[R];
            l1[R]=r1[R]=mx1[R]=sum1[R]=0;
            tag[L]=tag[R]=0;
        }
        else if (tmp==1)
        {
            l0[L]=r0[L]=mx0[L]=sum0[L]=0;
            l1[L]=r1[L]=mx1[L]=sum1[L]=size[L];
            l0[R]=r0[R]=mx0[R]=sum0[R]=0;
            l1[R]=r1[R]=mx1[R]=sum1[R]=size[R];
            tag[L]=tag[R]=1;
        }
        else
        {
            swap(l0[L],l1[L]); swap(r0[L],r1[L]); swap(sum0[L],sum1[L]); swap(mx0[L],mx1[L]);
            swap(l0[R],l1[R]); swap(r0[R],r1[R]); swap(sum0[R],sum1[R]); swap(mx0[R],mx1[R]);
            if (tag[L]==-1) tag[L]=2; 
            else if (tag[L]==0) tag[L]=1;
            else if (tag[L]==1) tag[L]=0;
            else tag[L]=-1;
            if (tag[R]==-1) tag[R]=2; 
            else if (tag[R]==0) tag[R]=1;
            else if (tag[R]==1) tag[R]=0;
            else tag[R]=-1;
        }
    }
}
void build(int k,int x,int y)
{
    l[k]=x; r[k]=y; size[k]=r[k]-l[k]+1; tag[k]=-1;
    if (l[k]==r[k]) 
    {
        if (a[l[k]]==0) l0[k]=r0[k]=mx0[k]=sum0[k]=1;
        else l1[k]=r1[k]=mx1[k]=sum1[k]=1;
        return;
    }
    int mid=l[k]+r[k]>>1;
    build(k<<1,x,mid); build(k<<1|1,mid+1,y);
    pushup(k);
}
void change(int k,int x,int y,int val)
{
    pushdown(k);
    if (l[k]==x&&r[k]==y)
    {
        tag[k]=val;
        if (val==0)
        {
            l0[k]=r0[k]=mx0[k]=sum0[k]=size[k];
            l1[k]=r1[k]=mx1[k]=sum1[k]=0;
        }
        else
        {
            l0[k]=r0[k]=mx0[k]=sum0[k]=0;
            l1[k]=r1[k]=mx1[k]=sum1[k]=size[k];
        }
        return;
    }
    int mid=l[k]+r[k]>>1;
    if (y<=mid) change(k<<1,x,y,val);
    else if (x>mid) change(k<<1|1,x,y,val);
    else change(k<<1,x,mid,val),change(k<<1|1,mid+1,y,val);
    pushup(k);
}
void rever(int k,int x,int y)
{
    pushdown(k);
    if (l[k]==x&&r[k]==y)
    {
        tag[k]=2;
        swap(l0[k],l1[k]); swap(r0[k],r1[k]); swap(sum0[k],sum1[k]); swap(mx0[k],mx1[k]);
        return;
    }
    int mid=l[k]+r[k]>>1;
    if (y<=mid) rever(k<<1,x,y);
    else if (x>mid) rever(k<<1|1,x,y);
    else rever(k<<1,x,mid),rever(k<<1|1,mid+1,y);
    pushup(k);
}
int query1(int k,int x,int y)
{
    if (l[k]==x&&r[k]==y) return sum1[k];
    pushdown(k);
    int mid=l[k]+r[k]>>1;
    if (y<=mid) return query1(k<<1,x,y);
    else if (x>mid) return query1(k<<1|1,x,y);
    else return query1(k<<1,x,mid)+query1(k<<1|1,mid+1,y);
}
void query2(int k,int x,int y)
{
    if (l[k]==x&&r[k]==y)
    {
        stack[++top]=k;
        return;
    }
    pushdown(k);
    int mid=l[k]+r[k]>>1;
    if (y<=mid) query2(k<<1,x,y);
    else if (x>mid) query2(k<<1|1,x,y);
    else query2(k<<1,x,mid),query2(k<<1|1,mid+1,y); 
}
int work()
{
    int nowl0=l0[stack[1]],nowr0=r0[stack[1]],nowl1=l1[stack[1]],nowr1=r1[stack[1]],nowsum0=sum0[stack[1]],nowsum1=sum1[stack[1]],nowmx0=mx0[stack[1]],nowmx1=mx1[stack[1]],nowsize=size[stack[1]];
    for (int i=2;i<=top;i++)
    {
        int lastl0=nowl0,lastl1=nowl1,lastr0=nowr0,lastr1=nowr1,lastsum0=nowsum0,lastsum1=nowsum1,lastmx0=nowmx0,lastmx1=nowmx1,lastsize=nowsize;
        int R=stack[i];
        nowl0=lastl0; nowr0=r0[R];
        nowl1=lastl1; nowr1=r1[R];
        if (lastl0==lastsize) nowl0+=l0[R];
        if (lastl1==lastsize) nowl1+=l1[R];
        if (r0[R]==size[R]) nowr0+=lastr0;
        if (r1[R]==size[R]) nowr1+=lastr1;
        nowsum0=lastsum0+sum0[R];
        nowsum1=lastsum1+sum1[R];
        nowmx0=max(lastr0+l0[R],max(lastmx0,mx0[R]));
        nowmx1=max(lastr1+l1[R],max(lastmx1,mx1[R]));   
        nowsize=lastsize+size[R];
    }
    return nowmx1;
}
int main()
{   
    n=read(); m=read();
    for (int i=1;i<=n;i++) a[i]=read();
    build(1,1,n);
    int tmp;
    for (int i=1;i<=m;i++)
    {
        int opt=read(),x=read()+1,y=read()+1;
        switch (opt)
        {
            case 0:
                change(1,x,y,0);
                break;
            case 1:
                change(1,x,y,1);
                break;
            case 2:
                rever(1,x,y);
                break;
            case 3:
                printf("%d\n",query1(1,x,y));
                break;
            case 4:
                top=0;
                query2(1,x,y);
                printf("%d\n",work());
                break;
        }
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: