码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces Round #254 (Div. 1) D - DZY Loves Strings

时间:2019-01-14 20:13:42      阅读:165      评论:0      收藏:0      [点我收藏+]

标签:sig   mes   问题   大小   sqrt   blog   ref   hash   min   

D - DZY Loves Strings

思路:感觉这种把询问按大小分成两类解决的问题都很不好想。。

https://codeforces.com/blog/entry/12959

题解说得很清楚啦。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ull unsigned long long

using namespace std;

const int N = 1e5 + 7;
const int M = 1e6 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-8;
const double PI = acos(-1);

int n, B;
string s, str;
string p[N], q[N];
int hsp[N], hsq[N], mn[M], len[M];
int gg[N][5];
vector<int> vc[M];

bool vis[M];
int ans[N];

inline int get_hash(string& a) {
    int ans = 0;
    for(int i = 0; i < a.size(); i++)
        ans *= 27, ans += a[i]-a+1;
    return ans;
}

int Merge(vector<int>& a, vector<int>& b, int lena, int lenb) {
    int ans = inf;
    if(!a.size() || !b.size()) return ans;
    for(int i = 0, j = 0; i < a.size(); i++) {
        while(j+1 < b.size() && a[i] >= b[j]) j++;
        if(j-1 >= 0) ans = min(ans, max(a[i]+lena, b[j-1]+lenb) - min(b[j-1], a[i]));
        ans = min(ans, max(a[i]+lena, b[j]+lenb) - min(b[j], a[i]));
    }
    return ans;
}

int main() {
    memset(gg, -1, sizeof(gg));
    memset(ans, inf, sizeof(ans));
    cin >> s;
    scanf("%d", &n);

    B = ceil(4*s.size() / sqrt(n));
    for(int i = 1; i <= n; i++) {
        cin >> p[i] >> q[i];
        hsp[i] = get_hash(p[i]);
        hsq[i] = get_hash(q[i]);
    }
    for(int i = 0; i < s.size(); i++) {
        str = s.substr(i, 4);
        while(str.size()) {
            int hs = get_hash(str);
            vc[hs].push_back(i);
            len[hs] = str.size();
            gg[i][str.size()] = hs;
            str.pop_back();
        }
    }
    for(int i = 0; i <= 560000; i++) {
        if(vc[i].size() >= B) {
            for(int j = 1; j <= n; j++) mn[hsp[j]] = mn[hsq[j]] = inf;
            for(int j = 0, k = 0; j < s.size(); j++) {
                while(k+1 < vc[i].size() && j >= vc[i][k]) k++;
                for(int z = 1; z <= 4; z++) {
                    int hs = gg[j][z];
                    if(hs == -1) continue;
                    if(k-1 >= 0) mn[hs] = min(mn[hs], max(vc[i][k-1]+len[i], j+len[hs]) - min(j, vc[i][k-1]));
                    mn[hs] = min(mn[hs], max(vc[i][k]+len[i], j+len[hs]) - min(j, vc[i][k]));
                }
            }
            for(int j = 1; j <= n; j++) {
                if(hsp[j] == i) ans[j] = min(ans[j], mn[hsq[j]]), vis[j] = true;
                else if(hsq[j] == i) ans[j] = min(ans[j], mn[hsp[j]]), vis[j] = true;
            }
        }
    }
    int cnt = 0, mx = 0;
    for(int i = 1; i <= n; i++) {
        if(!vis[i])
            ans[i] = Merge(vc[hsp[i]], vc[hsq[i]], len[hsp[i]], len[hsq[i]]);
    }
    for(int i = 1; i <= n; i++) printf("%d\n", ans[i] == inf ? -1 : ans[i]);
    return 0;
}

/*
*/

 

Codeforces Round #254 (Div. 1) D - DZY Loves Strings

标签:sig   mes   问题   大小   sqrt   blog   ref   hash   min   

原文地址:https://www.cnblogs.com/CJLHY/p/10268517.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!