解析:
线段树模板题,不同颜色的个数可以用或运算,最后只要看有几个1.
因为颜色有60个 1<<60 要用long long
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+1000;
typedef long long ll;
ll tr[N<<3],lazy[N<<3];
int n,m,l,r,c;
void push_up(int root)
{
tr[root]=tr[root<<1]|tr[root<<1|1];
}
void push_down(int root)
{
if(lazy[root])
{
lazy[root<<1]|=lazy[root];
lazy[root<<1|1]|=lazy[root];
tr[root<<1]|=lazy[root];
tr[root<<1|1]|=lazy[root];
lazy[root]=0;
}
}
void build(int root,int l,int r)
{
if(l==r)
{
tr[root]=lazy[root]=0;
return ;
}
int mid=l+r>>1;
build(root<<1,l,mid);build(root<<1|1,mid+1,r);
push_up(root);
}
void update(int root,int l,int r,int ql,int qr,ll val)
{
if(ql<=l&&qr>=r)
{
tr[root]|=val;
lazy[root]|=val;
return ;
}
push_down(root);
int mid=l+r>>1;
if(ql<=mid) update(root<<1,l,mid,ql,qr,val);
if(qr>mid) update(root<<1|1,mid+1,r,ql,qr,val);
push_up(root);
}
ll query(int root,int l,int r,int ql,int qr)
{
if(ql<=l&&qr>=r) return tr[root];
push_down(root);
int mid=l+r>>1;
ll res=0;
if(ql<=mid) res|=query(root<<1,l,mid,ql,qr);
if(qr>mid) res|=query(root<<1|1,mid+1,r,ql,qr);
return res;
}
int main()
{
int op;
while(~scanf("%d %d",&n,&m))
{
build(1,1,n);
while(m--)
{
scanf("%d",&op);
if(op==1)
{
scanf("%d %d %d",&l,&r,&c);
ll val=1LL<<c;
update(1,1,n,l,r,val);
}
else
{
scanf("%d %d",&l,&r);
ll res=query(1,1,n,l,r);
int ans=0;
while(res)
{
if(res&1) ans++;
res>>=1;
}
cout<<ans<<endl;
}
}
}
}