zoukankan      html  css  js  c++  java
  • Codecraft-18 and Codeforces Round #458 (Div. 1 + Div. 2, combined) F. Substrings in a String

    http://codeforces.com/contest/914/problem/F

    以前做过一个类似的,但是查询的子串长度最多是10,这个时候就是用bit + hash做了。这是因为改变一个字符,只需改变它后面10个的hash值就够了,多余的不影响,因为查询去不到那里。(只记得是今年的网络赛来的)

    但是这题查询只给了一个长度总和,没上一题好做。

    这题的思路应该是用bitset查询。

    把各个字母拆成不同的bitset,比如abc,拆成

    a: 001

    b: 010

    c: 100

    然后,a & (b >> 1) & (c >> 2)即可。

    最后统计bitset的L + lent - 1,R区间中有多少个1,这里需要用移位加速,不然TLE.

    bitset的第0位,是最右边的。这也刚好, 相当于把整个串反转了    >> 后也可以把不需要的剔除

    >> L位,是把左边的无关字符去掉

    >> (R - L + 2 - lent)位是可以算出来的

    具体就是,从L开始,假设有x位是合法的贡献,那么有L + x - 1 + lent - 1 = R

    #include <bits/stdc++.h>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    const int MAXN = 1e5 + 2;
    bitset<MAXN> f[27];
    char str[MAXN];
    char t[MAXN];
    bitset<MAXN> getAns;
    void work() {
        scanf("%s", str + 1);
        int lenstr = strlen(str + 1);
        for (int i = 1; i <= lenstr; ++i) f[str[i] - 'a'][i] = 1;
        int q;
        scanf("%d", &q);
        while (q--) {
            int op;
            scanf("%d", &op);
            if (op == 1) {
                int pos;
                scanf("%d%s", &pos, t);
                f[str[pos] - 'a'][pos] = 0;
                str[pos] = t[0];
                f[str[pos] - 'a'][pos] = 1;
            } else {
                int L, R;
                scanf("%d%d%s", &L, &R, t + 1);
                int lent = strlen(t + 1);
                if (lent > R - L + 1) {
                    printf("0
    ");
                    continue;
                }
                getAns.reset();
                getAns = ~getAns;
                for (int i = 1; i <= lent; ++i) {
                    getAns &= (f[t[i] - 'a'] >> (i - 1));
                }
    //            cout << getAns << endl;
                getAns >>= L;
    //            cout << getAns << endl;
                int ans = getAns.count();
                getAns >>= (R - L + 2 - lent);
    //            cout << getAns << endl;
                ans -= getAns.count();
                printf("%d
    ", ans);
            }
        }
    }
    
    int main() {
    #ifdef local
        freopen("data.txt", "r", stdin);
    //    freopen("data.txt", "w", stdout);
    #endif
        work();
        return 0;
    }
    View Code
  • 相关阅读:
    Js 作用域链
    JS 上下文模式
    javascript
    HTTP概念进阶
    JavaScript运行机制详解
    浅谈循环中setTimeout执行顺序问题
    Js 运行机制 (重点!!)
    javascript
    jQuery 知识点总结
    Educational Codeforces Round 87 (Rated for Div. 2)
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/8324625.html
Copyright © 2011-2022 走看看