[jzoj4603]【NOIP2016提高A组模拟7.15】颜料大乱斗

来源:互联网 发布:cms监控软件安卓版 编辑:程序博客网 时间:2024/04/29 18:03

Description

Solution

线段树练手题

坑点

  1. 区间可能左端点>右端点

  2. 白色的颜色用1表示

所有人都说要开 30 棵线段树

既然只有30位合成一下不是很舒服么???

Code

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define fo(i,x,y) for (int pq = (y),i = (x);i <= pq;++ i)#define fd(i,x,y) for (int pq = (y),i = (x);i >= pq;-- i)#define oo 2139062143using namespace std;typedef double db;typedef long long ll;int lowbit(int x) {return((x)&(-x));}int min(int x,int y){return (x>y)?(y):(x);}int max(int x,int y){return (x>y)?(x):(y);}const int N=100100,C=33;int n,c,m;int x,y,z;int t[N*8];int lz[N*8];void build(int x,int l,int r){    if(l==r)    {        t[x]=1;        return;    }    int mid=(l+r)>>1;    build(x<<1,l,mid),build(x<<1|1,mid+1,r);    t[x]=t[x<<1]|t[x<<1|1];}int tot=0;void updata(int x,int y){    t[x]=y;    lz[x]=y;}void down(int x){    if(!lz[x]) return;    updata(x<<1,lz[x]);    updata(x<<1|1,lz[x]);    lz[x]=0;}void change(int x,int l,int r,int ql,int qr,int qv){    if(l>r)return;    if(l==ql&&r==qr)    {        updata(x,qv);        return;    }    down(x);    int mid=(l+r)>>1;         if(qr<=mid) change(x<<1,l,mid,ql,qr,qv);    else if(ql>=mid+1) change(x<<1|1,mid+1,r,ql,qr,qv);    else change(x<<1,l,mid,ql,mid,qv),change(x<<1|1,mid+1,r,mid+1,qr,qv);    t[x]=t[x<<1]|t[x<<1|1];}int query(int x,int l,int r,int ql,int qr){    if(ql==l&&qr==r)         return(t[x]);    down(x);    int mid=(l+r)>>1;    int rt=0;             if(qr<=mid) rt|=query(x<<1,l,mid,ql,qr);    else if(ql>=mid+1) rt|=query(x<<1|1,mid+1,r,ql,qr);    else rt|=query(x<<1,l,mid,ql,mid)|query(x<<1|1,mid+1,r,mid+1,qr);    return rt;}int count(int x){    int rt=0;    while(x) x-=lowbit(x),++rt;    return rt;}int main(){    scanf("%d%d%d",&n,&c,&m);    build(1,1,n);    while(m--)    {        char ch=getchar();        while(ch!='C'&&ch!='P') ch=getchar();        scanf("%d%d",&x,&y);        if(x>y) swap(x,y);        if(ch=='C')        {            scanf("%d",&z);            change(1,1,n,x,y,1<<(z-1));        }        else        {            int ans=query(1,1,n,x,y);            printf("%d\n",count(ans));        }    }    return 0;}