poj2777

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll sum[500000],az[500000];
ll n,p,ans;
ll ql,qr,v,hh;
void pushdown(ll o){
if(az[o]!=0){
az[o*2]=az[o*2+1]=az[o];
az[o]=0;
}
}
void wf(ll o,ll l,ll r){
if(l==r)sum[o]=az[o];
else sum[o]=sum[o*2]|sum[o*2+1];
}
void mk(ll o,ll l,ll r){
if(ql<=l&&r<=qr)az[o]=1<<(v-1);
else{
pushdown(o);
ll m=l+(r-l)/2;
if(m>=ql)mk(o*2,l,m);else wf(o*2,l,m);
if(m<qr)mk(o*2+1,m+1,r);else wf(o*2+1,m+1,r);
}
wf(o,l,r);
}
void qz(ll o,ll l,ll r){
if(az[o]>=0){
ans=ans|az[o];
}else {
if(ql<=l&&qr>=r)
ans=ans|sum[o];
else{
ll m=l+(r-l)/2;
if(ql<=m)qz(o*2,l,m);
if(qr>m)qz(o*2+1,m+1,r);
}
}
}
int main(){
freopen("p.in","r",stdin);
ll t;
cin>>n>>t>>p;
for(int i=1;i<=p;i++){
char c;
cin>>c;
if(c=='P'){
ans=0;hh=0;
cin>>ql>>qr;
qz(1,1,n);
for(int i=0;i<t;i++)
if(ans&(1<<i))hh++;
cout<<hh<<endl;
}else{
cin>>ql>>qr>>v;
mk(1,1,n);
}
}
return 0;
}


[l,r]的颜色个数用30位二进制数表示。

线段树支持区间修改。

sum[o]=sum[o*2] or sum[o*2+1]

posted @ 2018-10-02 16:40  周栎  阅读(176)  评论(0编辑  收藏  举报