题目:https://www.nowcoder.com/acm/contest/105/H
思路:
和poj2777非常类似,只不过它是某一区间变为某颜色,这里是某一区间加上某颜色。
还是可以用sum的某一位来表示有没有这个颜色,然后lazy标记,按位或传递下去。
#include <bits/stdc++.h>
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define ll long long int
using namespace std;
const int maxn=1e5+10;
int n,m;
struct node{
int l,r;
ll sum;
}t[maxn<<2];
ll lazy[maxn<<2];
void down(int rt){
if(lazy[rt]){
ll tmp=lazy[rt];
lazy[rt<<1]|=tmp,lazy[rt<<1|1]|=tmp;
t[rt<<1].sum|=tmp,t[rt<<1|1].sum|=tmp;
lazy[rt]=0;
}
}
void build(int rt,int l,int r){
t[rt].l=l,t[rt].r=r;
t[rt].sum=0,lazy[rt]=0;
if(l==r){
return ;
}
int mid=(l+r)>>1;
build(lson),build(rson);
}
void update(int rt,int l,int r,int k){
if(l<=t[rt].l&&r>=t[rt].r){
lazy[rt]|=1ll<<k;
t[rt].sum|=1ll<<k;
return ;
}
down(rt);
int mid=(t[rt].l+t[rt].r)>>1;
if(l<=mid) update(rt<<1,l,r,k);
if(r>mid) update(rt<<1|1,l,r,k);
t[rt].sum=t[rt<<1].sum | t[rt<<1|1].sum;
}
ll query(int rt,int l,int r){
if(l<=t[rt].l&&r>=t[rt].r) return t[rt].sum;
down(rt);
int mid=(t[rt].l+t[rt].r)>>1;
ll ans=0;
if(l<=mid) ans|=query(rt<<1,l,r);
if(r>mid) ans|=query(rt<<1|1,l,r);
return ans;
}
int main(){
while(scanf("%d%d",&n,&m)==2){
build(1,1,n);
while(m--){
int f,l,r,k;
scanf("%d",&f);
if(f==1){
scanf("%d%d%d",&l,&r,&k);
update(1,l,r,k);
}
else{
scanf("%d%d",&l,&r);
ll ans=query(1,l,r);
int cnt=0;
while(ans){
if(ans&1)
cnt++;
ans>>=1;
}
printf("%d\n",cnt);
}
}
}
return 0;
}