Statistics Color ~ Segment Tree

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

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)

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;
}

 



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325085339&siteId=291194637