444D
分类
首先我们要对询问分类,如果相差log级别就第一种询问,否则第二种。
第一种直接暴力lower_bound,复杂度玄学
第二种归并,复杂度玄学
但是就是过了。感觉很容易卡。
#include<bits/stdc++.h> using namespace std; const int N = 400010, LOG = 16; int q, cnt; string s, s1, s2; map<string, int> mp; vector<int> appear[N]; map<pair<int, int>, int> mem; int Hash(string &s, int pos, int len) { string ss = s.substr(pos, len); if(mp.find(ss) == mp.end()) mp[ss] = ++cnt; return mp[ss]; } int main() { ios :: sync_with_stdio(false); cin.tie(0); cin >> s >> q; for(int i = 0; i < s.length(); ++i) for(int j = 1; j <= 4; ++j) appear[Hash(s, i, j)].push_back(i); while(q--) { cin >> s1 >> s2; int l1 = s1.length(), l2 = s2.length(), a = Hash(s1, 0, l1), b = Hash(s2, 0, l2); if(l1 > l2) { swap(l1, l2); swap(a, b); } if(mem[make_pair(a, b)]) { cout << mem[make_pair(a, b)] << endl; continue; } int &ans = mem[make_pair(a, b)]; ans = 1 << 29; if(appear[a].size() * LOG < appear[b].size()) { for(int i = 0; i < appear[a].size(); ++i) { int p = lower_bound(appear[b].begin(), appear[b].end(), appear[a][i]) - appear[b].begin(); if(p != appear[b].size()) ans = min(ans, max(appear[a][i] + l1 - 1, appear[b][p] + l2 - 1) - min(appear[a][i], appear[b][p]) + 1); if(p < appear[b].size() - 1) ans = min(ans, max(appear[a][i] + l1, appear[b][p + 1] + l2) - min(appear[a][i], appear[b][p + 1]) + 1); if(p > 0) ans = min(ans, max(appear[a][i] + l1, appear[b][p - 1] + l2) - min(appear[a][i], appear[b][p - 1]) + 1); } } else { int i = 0, j = 0; while(i < appear[a].size() && j < appear[b].size()) { int pa = appear[a][i], pb = appear[b][j]; ans = min(ans, max(pa + l1 - 1, pb + l2 - 1) - min(pa, pb) + 1); if(pa < pb) ++i; else ++j; } } cout << ((ans == 1 << 29) ? ans = -1 : ans) << endl; } return 0; }