POJ2777(线段树裸题)

题目:http://poj.org/problem?id=2777

别忘了各地的return;

有可能输入的L<R,手动swap;

似乎是多组输入?

pushup和pushdown的位置。

(原来pushup只有一行)

要开四倍数组。是这种写法的原因吧。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=400005;
int n,m,q,L,R,co;
char ch;
long long col[N],lazy[N];
void pushdown(int cnt)
{
    if(lazy[cnt])
    {
        col[cnt*2]=lazy[cnt];
        col[cnt*2+1]=lazy[cnt];
        lazy[cnt*2]=lazy[cnt];
        lazy[cnt*2+1]=lazy[cnt];
        lazy[cnt]=0;
    }
}
void pushup(int cnt)
{
    col[cnt]=(col[cnt*2]|col[cnt*2+1]);
}
void add(int l,int r,int cnt)
{
    if(l>=L&&r<=R)
    {
        col[cnt]=co;
        lazy[cnt]=co;
        return;
    }
    pushdown(cnt);
    int mid=(l+r)/2;
    if(mid>=L)add(l,mid,cnt*2);
    if(mid<R)add(mid+1,r,cnt*2+1);
    pushup(cnt);
}
long long query(int l,int r,int cnt)
{
    if(l>=L&&r<=R)
    {
        return col[cnt];
    }
    long long ans=0;
    pushdown(cnt);
    int mid=(l+r)/2;
    if(mid>=L)ans|=query(l,mid,cnt*2);
    if(mid<R)ans|=query(mid+1,r,cnt*2+1);
    return ans;
}
void build(int l,int r,int cnt)
{
    col[cnt]=1;
    if(l==r)return;
    int mid=(l+r)/2;
    build(l,mid,cnt*2);
    build(mid+1,r,cnt*2+1);
}
int main()
{
    while(scanf("%d%d%d",&n,&m,&q)!=EOF)
    {
        build(1,n,1);
        memset(lazy,0,sizeof lazy);
        for(int i=1;i<=q;i++)
        {
            scanf(" %c%d%d",&ch,&L,&R);
            if(L>R)swap(L,R);//
            if(ch=='C')
            {
                scanf("%d",&co);
                co=(1<<(co-1));
                add(1,n,1);
            }
            if(ch=='P')
            {
                int ret=0;
                long long ans=query(1,n,1);
                while(ans)
                {
                    ret+=(ans&1);
                    ans>>=1;
                }
                printf("%d\n",ret);
            }
        }
    }
    return 0;
}

 

posted on 2018-04-05 10:25  Narh  阅读(154)  评论(0编辑  收藏  举报

导航