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;
}
View Code

 

posted @ 2017-07-07 00:24  19992147  阅读(298)  评论(0编辑  收藏  举报