Link: https://www.nowcoder.com/acm/contest/105/H
Source: Niuke.com
Time limit: C/C++ 1 second, other languages 2 seconds
Space limit: C/C++ 32768K, other languages 65536K
64bit IO Format: %lld
Space limit: C/C++ 32768K, other languages 65536K
64bit IO Format: %lld
Topic description
The n buckets are arranged in order, and we number the buckets with 1~n. There are two operations:
1 lrc put a ball of color c into each bucket in the lrc interval [l,r] (1≤l,r≤n,l≤r,0≤c≤60)
2 lr query How many balls of different colors are in the bucket in the interval [l,r] (1≤l,r≤n,l≤r)
1 lrc put a ball of color c into each bucket in the lrc interval [l,r] (1≤l,r≤n,l≤r,0≤c≤60)
2 lr query How many balls of different colors are in the bucket in the interval [l,r] (1≤l,r≤n,l≤r)
Enter description:
There are multiple sets of data, for each set of data:
the first line has two integers n, m (1≤n, m≤100000) and
the next m lines represent m operations, the format is as shown in the title.
Output description:
For each operation number 2, output an integer representing the result of the query.
Example 1
enter
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
output
2 3 2 4 3
This question is a bare line segment tree question, which is very convenient to handle with bit operations
Bitwise OR operator (|)
The two objects participating in the operation are "ored" according to the binary bit.
Operation rules: 0|0=0; 0|1=1; 1|0=1; 1|1=1;
That is: as long as one of the two objects participating in the operation is 1, its value is 1.
#include <cstdio> #include <algorithm> #include <vector> #include <queue> #include <cstring> #include <string> using namespace std; const int maxn = 1e5 + 10; typedef long long LL ; LL add[maxn << 2], sum[maxn << 2]; void pushup(LL rt) { sum[rt] = sum[rt << 1] | sum[rt << 1 | 1]; } void pushdown(LL rt) { if (add[rt]) { add[rt << 1] |= add[rt]; add[rt << 1 | 1] |= add[rt]; sum[rt << 1] |= add[rt]; sum[rt << 1 | 1] |= add[rt]; add[rt] = 0; } } void updata(LL x, LL y, LL z, LL l, LL r, LL rt) { if (r<x || l>y ) return ; if (x <= l && r <= y) { sum[rt] |= z; add[rt] |= z; return ; } pushdown(rt); LL m = (l + r) >> 1; updata(x, y, z, l, m, rt << 1); updata(x, y, z, m + 1, r, rt << 1 | 1); pushup(rt); } LL query(LL x, LL y, LL l, LL r, LL rt ) { if (x <= l && r <= y) return sum[rt]; pushdown(rt); LL ans = 0; LL mid = (l + r) >> 1; if (y > mid) ans |= query(x, y, mid + 1, r, rt << 1 | 1); if (x <= mid) ans |= query(x, y, l, mid, rt << 1); return ans; } LL getx(LL x) { LL ans = 0; while(x) { years += x% 2 ; x /= 2; } return ans; } int main() { LL n, m; //freopen("DATA.txt", "r", stdin); while(scanf("%lld%lld", &n, &m) != EOF) { memset(sum, 0, sizeof(sum)); memset(add, 0, sizeof(add)); while(m--) { LL l, r, x; scanf("%lld", &x); scanf("%lld%lld", &l, &r); if(x == 1) { LL a; scanf("%lld", &a); updata(l, r, (LL)1 << a, 1, n, 1 ); } else { LL t = query(l, r, 1, n, 1); printf("%lld\n", getx(t)); } } } return 0; }