zoukankan      html  css  js  c++  java
  • C. Two strings 二分 + 预处理

    http://codeforces.com/contest/762/problem/C

    第一个串str[],第二个sub[]

    预处理出prefix[i]表示sub的前i位和str[]的最长lcs去到str[]的最小的位置,如果某一位i不成立了,就设为inf

    由于处理的时候,指针指向str[]的是单调递增的,所以预处理复杂度O(n),同样预处理suffix数组。

    那么就是求一个位置,使得两个数组不会相交。

    但是如果会相交,那么应该让那个数组退后一步呢,一开始用数组相邻差的绝对值来确定,因为移动得多的那个必定更优。

    但是不然,test5就知道了。

    于是乎就直接处理出所有的prefix[i],所对应的最优suffix[],这个可以在suffix[]中二分搞定。

    话说二分可真有用。

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <assert.h>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    #include <bitset>
    vector<int>pos[26];
    const int maxn = 1e5 + 20;
    char str[maxn], sub[maxn];
    int lenstr, lensub;
    int L, R;
    int prefix[maxn];
    int suffix[maxn];
    void init() {
        int p1 = 0;
        for (int i = 1; i <= lensub; ++i) {
            if (pos[sub[i] - 'a'].size() == 0) break;
            if (pos[sub[i] - 'a'].back() <= p1) break;
            prefix[i] = upper_bound(pos[sub[i] - 'a'].begin(), pos[sub[i] - 'a'].end(), p1) - pos[sub[i] - 'a'].begin();
            prefix[i] = pos[sub[i] - 'a'][prefix[i]];
            p1 = prefix[i];
        }
    //    for (int i = 1; i <= lensub; ++i) {
    //        cout << prefix[i] << " ";
    //    }
        p1 = lenstr;
        for (int i = lensub; i >= 1; --i) {
            while (p1 >= 1) {
                if (str[p1] == sub[i]) break;
                p1--;
            }
            if (p1 == 0) break;
            suffix[i] = p1;
            p1--;
        }
    //    for (int i = 1; i <= lensub; ++i) {
    //        cout << suffix[i] << " ";
    //    }
    }
    void work() {
        scanf("%s%s", str + 1, sub + 1);
        lenstr = strlen(str + 1);
        lensub = strlen(sub + 1);
        memset(prefix, 0x3f, sizeof prefix);
        memset(suffix, -1, sizeof suffix);
        for (int i = 1; i <= lenstr; ++i) {
            pos[str[i] - 'a'].push_back(i);
        }
        prefix[0] = -1;
        suffix[lensub + 1] = inf;
        init();
        int pos1 = inf, pos2 = inf;
        for (int i = 1; i <= lensub; ++i) {
            if (prefix[i] == inf) {
                pos1 = i - 1;
                break;
            }
        }
        for (int i = lensub; i >= 1; --i) {
            if (suffix[i] == -1) {
                pos2 = i + 1;
                break;
            }
        }
        if (prefix[1] == inf && suffix[lensub] == -1) {
            cout << "-" << endl;
            return;
        }
        if (pos1 == inf || pos2 == inf) {
            cout << sub + 1 << endl;
            return;
        }
        if (pos1 == 0) {
            assert(pos2 != lensub + 1);
            for (int i = pos2; i <= lensub; ++i) {
                printf("%c", sub[i]);
            }
            return;
        }
        if (pos2 == lensub + 1) {
            for (int i = 1; i <= pos1; ++i) {
                printf("%c", sub[i]);
            }
            return;
        }
        int anslen = -1;
        for (int i = 0; i <= pos1; ++i) {
            int topos = upper_bound(suffix + pos2, suffix + 1 + lensub, prefix[i]) - suffix;
    //        cout << suffix[topos] << endl;
            if (anslen < i + lensub - topos + 1) {
                anslen = i + lensub - topos + 1;
                L = i + 1;
                R = topos - 1;
            }
        }
    //    cout << L << " " << R << endl;
        for (int i = 1; i <= lensub; ++i) {
            if (i == L) {
                i = R;
                continue;
            }
            printf("%c", sub[i]);
        }
    
    }
    
    int main() {
    #ifdef local
        freopen("data.txt", "r", stdin);
    //    freopen("data.txt", "w", stdout);
    #endif
        work();
        return 0;
    }
    View Code
  • 相关阅读:
    ubuntu /etc/rc.local 不执行
    HTML中设置页面内嵌跳转
    JS使用AudioContext播放音乐
    Unity实现摄像机以某个物体为中心旋转
    Unity中实现通过鼠标对物体进行旋转平移缩放
    解决Windows上无法创建以点开头的文件问题
    解决FBX模型导入Unity后没有贴图的问题
    nedb中使用update更新数据的原理
    Electron 渲染进程中解决require is not defined的问题
    Base64转Blob的方式
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6352219.html
Copyright © 2011-2022 走看看