• 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
  • 相关阅读:
    sqlite3 学习
    解释内存中的栈(stack)、堆(heap)和静态区(static area)的用法
    HTML基本语法
    linux shell脚本、命令学习
    laravel 缓存相关常用操作
    【扩展推荐】Intervention/image 图片处理
    【Laravel】 常用的artisian命令
    laravel开发调试工具laravel-debugbar的安装
    为PhpStorm添加Laravel 代码智能提示功能
    laravel5.5 安装
  • 原文地址:https://www.cnblogs.com/19992147orz/p/7129194.html
Copyright © 2020-2023  润新知