H-统计颜色
题目描述
n个桶按顺序排列,我们用1~n给桶标号。有两种操作:
1 l r c 区间[l,r]中的每个桶中都放入一个颜色为c的球 (1≤l,r ≤n,l≤r,0≤c≤60)
2 l r 查询区间[l,r]的桶中有多少种不同颜色的球 (1≤l,r ≤n,l≤r)
输入
有多组数据,对于每组数据:
第一行有两个整数n,m(1≤n,m≤100000)
接下来m行,代表m个操作,格式如题目所示。
输出
对于每个2号操作,输出一个整数,表示查询的结果。
样例
输入
10 10
1 1 2 0
1 3 4 1
2 1 4
1 5 6 2
2 1 6
1 7 8 1
2 3 8
1 8 10 3
2 1 10
2 3 8
输出
2
3
2
4
3
题意
模板题,,
AC代码
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define CLR(a,b) memset(a,(b),sizeof(a))
#define ls st<<1
#define rs st<<1|1
const int MAXN = 1e5+10;
struct node {
int l, r;
LL x, lazy;
}tree[MAXN<<2];
void build(int l, int r, int st) {
tree[st].l = l, tree[st].r = r;
tree[st].x = 0, tree[st].lazy = 0;
if(l == r)
return;
int mid = (l+r) >> 1;
build(l,mid,ls);
build(mid+1,r,rs);
}
void push_down(int st) {
if(tree[st].lazy) {
tree[ls].x |= tree[st].lazy;
tree[rs].x |= tree[st].lazy;
tree[ls].lazy |= tree[st].lazy;
tree[rs].lazy |= tree[st].lazy;
}
tree[st].lazy = 0;
}
void update(int l, int r, int st, int val) {
if(tree[st].l>=l && tree[st].r<=r) {
LL x = 1;
x = x<<val;
tree[st].x |= x;
tree[st].lazy |= x;
return;
}
push_down(st);
int mid = (tree[st].l+tree[st].r) >> 1;
if(r <= mid)
update(l,r,ls,val);
else if(l > mid)
update(l,r,rs,val);
else {
update(l,mid,ls,val); update(mid+1,r,rs,val);
}
tree[st].x = tree[ls].x|tree[rs].x;
}
LL kk;
void query(int l, int r, int st) {
if(l==tree[st].l && tree[st].r==r) {
kk |= tree[st].x;
kk |= tree[st].lazy;
return;
}
push_down(st);
tree[st].x = tree[ls].x|tree[rs].x;
int mid = (tree[ls].l+tree[st].r) >> 1;
if(r <= mid)
query(l,r,ls);
else if(l > mid)
query(l,r,rs);
else {
query(l,mid,ls);query(mid+1,r,rs);
}
}
LL sum(LL x) {
LL ans = 0;
while(x) {
if(x&1)
ans++;
x >>= 1;
}
return ans;
}
int main() {
ios::sync_with_stdio(false);
int n, m;
while(cin >> n >> m) {
build(1,n,1);
for(int i = 0; i < m; i++) {
int op, x, y, z;
cin >> op;
if(op == 1) {
cin >> x >> y >> z;
update(x,y,1,z);
}
else {
cin >> x >> y;
kk = 0;
query(x,y,1);
cout << sum(kk) << endl;
}
}
}
return 0;
}