思路:感觉这种把询问按大小分成两类解决的问题都很不好想。。
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 ", ans[i] == inf ? -1 : ans[i]); return 0; } /* */