链接:
https://www.nowcoder.com/acm/contest/105/H
来源:牛客网
1 5 6 22 1 61 7 8 12 3 81 8 10 32 1 102 3 8
来源:牛客网
题目描述
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)
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号操作,输出一个整数,表示查询的结果。
示例1
输入
10 10 1 1 2 0 1 3 4 1 2 1 4
#include <bits/stdc++.h>
using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
const int maxn = 1e5 + 7;
bitset<61>A[maxn<<2];
bitset<61> lazy[maxn<<2];
void pushup(int rt)
{
A[rt] = A[rt<<1] | A[rt<<1|1];
}
void pushdown(int rt)
{
if(lazy[rt].any()) {
lazy[rt<<1] |= lazy[rt];
lazy[rt<<1|1] |= lazy[rt];
A[rt<<1] |= lazy[rt];
A[rt<<1|1] |= lazy[rt];
lazy[rt] = 0;
}
}
bitset<61> query(int L, int R, int l, int r, int rt)
{
if(L <= l && r <= R) {
return A[rt];
}
pushdown(rt);
int mid = (l + r) / 2;
bitset<61> ans;
if(L <= mid) ans |= query(L,R,lson);
if(R > mid) ans |= query(L,R,rson);
return ans;
}
void update(int p, int L, int R, int l, int r, int rt)
{
if(L <= l && r <= R) {
A[rt].set(p);
lazy[rt].set(p);
return ;
}
pushdown(rt);
int mid = (l + r) / 2;
if(L <= mid) update(p, L, R, lson);
if(R > mid) update(p, L, R, rson);
pushup(rt);
}
void build(int l, int r, int rt)
{
A[rt].reset();
lazy[rt].reset();
if(l == r) return;
int mid = (l + r) / 2;
build(lson);
build(rson);
}
int main()
{
int n, q, opt;
while(~scanf("%d %d", &n, &q)) {
build(1,n,1);
while(q --) {
scanf("%d", &opt);
if(opt == 1) {
int l, r, c;
scanf("%d %d %d", &l, &r, &c);
update(c, l, r, 1, n, 1);
} else {
int l, r;
scanf("%d %d", &l, &r);
printf("%d\n", query(l,r,1,n,1).count());
}
}
}
return 0;
}
/*
4 3
1 3 4 1
1 1 4 2
2 1 1
*/
1 5 6 22 1 61 7 8 12 3 81 8 10 32 1 102 3 8
输出
2 3 2 4 3
题解:直接用bitset按位异或来统计, 注意此时lazy标记的应用。