统计颜色-----------------------------线段树(或运算)

在这里插入图片描述
在这里插入图片描述
解析:
线段树模板题,不同颜色的个数可以用或运算,最后只要看有几个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;
		}
	}
	}	

}
发布了491 篇原创文章 · 获赞 11 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_43690454/article/details/104850215