• 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
    ", cnt);
            }
        }
    
        return 0;
    }
    
  • 相关阅读:
    MVC 与传统的 webform 的比较
    Visual Studio 类模板的修改
    2015-3-3
    SQL SERVER类型与C#类型对照
    数据库连接串的配置
    Could not load file or assembly 'System.Web.Mvc' or one of its dependencies. The located assembly's manifest definition does not
    多条查询sql语句返回多表数据集
    URL和搜索引擎优化
    XPath 语法示例
    如何把数据库的某个字段更新为另一个字段
  • 原文地址:https://www.cnblogs.com/YDDDD/p/11618889.html
Copyright © 2020-2023  润新知