zoukankan      html  css  js  c++  java
  • Codeforces #452 Div2 F

    #452 Div2 F

    题意

    给出一个字符串, m 次操作,每次删除区间 ([l,r]) 之间的字符 (c) ,输出最后得到的字符串。

    分析

    通过树状数组和二分,我们可以把给定的区间对应到在起始字符串上的区间。
    然后暴力去删字符即可(因为最多只会删掉等同于字符串长度的字符个数),总共只有 62 种字符,set 维护下位置。

    code

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 4e5 + 10;
    int n, m, f[N];
    void update(int x) {
        for(int i = x; i < N; i += i & -i) f[i]--;
    }
    int query(int x) {
        int s = 0;
        for(int i = x; i; i -= i & -i) s += f[i];
        return s;
    }
    int fd(int x) {
        int l = 1, r = n, mid;
        while(l < r) {
            mid = l + r >> 1;
            if(query(mid) < x) l = mid + 1;
            else r = mid;
        }
        return l;
    }
    char s[N];
    set<int> S[150];
    char ans[N];
    int main() {
        scanf("%d%d", &n, &m);
        scanf("%s", s + 1);
        for(int i = 1; i <= n; i++) {
            S[s[i]].insert(i);
            f[i + (i & -i)] += ++f[i];
        }
        while(m--) {
            char c[2];
            int l, r;
            scanf("%d%d%s", &l, &r, c);
            l = fd(l);
            r = fd(r);
            auto it = S[c[0]].lower_bound(l);
            while(it != S[c[0]].end() && *it <= r) {
                update(*it);
                auto itt = it;
                it++;
                S[c[0]].erase(itt);
            }
        }
        for(int i = 0; i < 150; i++) {
            for(int j : S[i]) ans[j] = i;
        }
        for(int i = 1; i <= n; i++) {
            if(ans[i]) cout << ans[i];
        }
        return 0;
    }
    
  • 相关阅读:
    Deformable 可变形的DETR
    https://start.aliyun.com/
    english note 111
    HTTP/2.0与HTTP/1.1协议区别
    什么是长连接
    使用pycharm
    Java使用率大幅度下降,Python使用率逐渐攀升
    SELECT command denied to user 'root'@'localhost' for table 'user'
    mysql 问题阅后归档
    响应式编程
  • 原文地址:https://www.cnblogs.com/ftae/p/8068248.html
Copyright © 2011-2022 走看看