Codeforces Round #590 (Div. 3) D. Distinct Characters Queries(线段树, 位运算)

Posted ydddd

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #590 (Div. 3) D. Distinct Characters Queries(线段树, 位运算)相关的知识,希望对你有一定的参考价值。

链接:

https://codeforces.com/contest/1234/problem/D

题意:

You are given a string s consisting of lowercase Latin letters and q queries for this string.

Recall that the substring s[l;r] of the string s is the string slsl+1…sr. For example, the substrings of "codeforces" are "code", "force", "f", "for", but not "coder" and "top".

There are two types of queries:

1 pos c (1≤pos≤|s|, c is lowercase Latin letter): replace spos with c (set spos:=c);
2 l r (1≤l≤r≤|s|): calculate the number of distinct characters in the substring s[l;r].

思路:

线段树维护二进制,二进制的每一位维护对应的字母在区间是否使用过, 合并区间就是与一下.

代码:

#include <bits/stdc++.h>
using namespace std;

const int MAXN = 1e5+10;
char s[MAXN];
int tree[MAXN*4];
int n, q;

void PushUp(int root)

    tree[root] = tree[root<<1] | tree[root<<1|1];


void Build(int root, int l, int r)

    if (l == r)
    
        tree[root] = 1<<(s[l]-'a');
        return;
    
    int mid = (l+r)/2;
    Build(root<<1, l, mid);
    Build(root<<1|1, mid+1, r);
    PushUp(root);


void Update(int root, int l, int r, int p, int c)

    if (l == r)
    
        tree[root] = 1<<c;
        return;
    
    int mid = (l+r)/2;
    if (p <= mid)
        Update(root<<1, l, mid, p, c);
    else
        Update(root<<1|1, mid+1, r, p, c);
    PushUp(root);


int Query(int root, int l, int r, int ql, int qr)

    if (qr < l || ql > r)
        return 0;
    if (ql <= l && r <= qr)
        return tree[root];
    int mid = (l+r)/2;
    int res = 0;
    res |= Query(root<<1, l, mid, ql, qr);
    res |= Query(root<<1|1, mid+1, r, ql, qr);
    return res;


int main()

    scanf("%s", s+1);
    n = strlen(s+1);
    Build(1, 1, n);
    scanf("%d", &q);
    int op, l, r;
    char val;
    while (q--)
    
        scanf("%d", &op);
        if (op == 1)
        
            scanf("%d %c", &l, &val);
            Update(1, 1, n, l, val-'a');
        
        else
        
            scanf("%d %d", &l, &r);
            int res = Query(1, 1, n, l, r);
            int cnt = 0;
            while (res)
            
                if (res&1)
                    cnt++;
                res >>= 1;
            
            printf("%d\n", cnt);
        
    

    return 0;

以上是关于Codeforces Round #590 (Div. 3) D. Distinct Characters Queries(线段树, 位运算)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #590 (Div. 3)

Codeforces Round #590 (Div. 3) C. Pipes

Codeforces Round #590 (Div. 3)

Codeforces Round #590 (Div. 3)

CodeForces Round #590 (Div 3)

Codeforces Round #590 (Div. 3)