1 条题解

  • 3
    @ 2025-3-8 19:07:16

    发现我们只需要预处理每个长度不大于 44 的字符串所在的区间即可,那么我们实际上需要的字符串是只有 4n4n 级别的,下文设 4n4nmm

    我们容易发现出现次数 >m> \sqrt{m} 的字符串数量是 m\sqrt{m} 级别的,于是我们可以直接预处理出对于每个出现次数 >m> \sqrt{m} 的字符串对于其余子串的答案,此处时间复杂度为 O(mm)O(m \sqrt{m})

    那么对于每一个询问,如果两个字符串有至少一个字符串出现次数是 >m> \sqrt{m} 的,那么此时我们已经预处理过了,直接输出答案即可,时间复杂度 O(1)O(1)。否则,如果两个字符串出现次数都是 m\le \sqrt{m} 的,那么此处我们直接枚举第一个字符串所在的位置,对于第二个字符串直接双指针维护即可,此处时间复杂度 m\sqrt{m},此处最劣时间复杂度为 O(qm)O(q \sqrt{m})

    总时间复杂度为 O((m+q)m)O((m+q) \sqrt{m})

    下面是参考代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define re register
    #define ll long long
    #define cll const ll
    #define forl(i,a,b) for(re ll (i)=(a);i<=(b);(i)++)
    #define forr(i,a,b) for(re ll (i)=(a);i>=(b);(i)--
    #define pii pair<ll,ll>
    #define mid ((l+r)>>1)
    #define lowbit(x) (x&-x)
    #define pb push_back
    #define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    #define endl '\n'
    #define QwQ return 0;
    #define x first
    #define y second
    template<typename T1,typename T2>bool Max(T1&x,T2 y){if(y>x)return x=y,1;return 0;}template<typename T1,typename T2>bool Min(T1&x,T2 y){if(y<x)return x=y,1;return 0;}ll Ss=chrono::steady_clock::now().time_since_epoch().count();mt19937_64 Apple(Ss);ll rand_lr(ll l,ll r){return Apple()%(r-l+1)+l;}
    ll _t_;
    string s;
    ll n,q;
    string s1,s2;
    map<string,ll>mp;
    string mp2[200010];
    ll a[200010],k;
    vector<pii>G[200010];
    ll sz[200010];
    ll sq=500;
    string x,y;
    vector<ll>big;
    int ans[300][100005];
    ll bigmp[200010];
    ll visbig[200010];
    ll ID;
    void Init()
    {
        forl(i,0,(ll)big.size()-1)
        {
            ll id=big[i];
            forl(j,1,4)
            {
                ll L=-1,szm=(ll)G[id].size()-1;
                forl(l,1,n-j+1)
                {
                    ll len=1e9;
                    ll r=l+j-1;
                    string S="";
                    forl(_,l,r)
                        S+=s[_];
                    while(L<szm && G[id][L+1].y<=r)
                        L++;
                    if(L!=-1)
                        Min(len,max(G[id][L].y,r)-min(l,G[id][L].x)+1);
                    if(L<szm)
                        Min(len,max(G[id][L+1].y,r)-min(l,G[id][L+1].x)+1);
                    Min(ans[i+1][mp[S]],len);
                }
            }
        }
    }
    void _clear(){}
    void solve()
    {
        _clear();
        cin>>s>>q;
        n=s.size();
        s=' '+s;
        forl(i,1,n)
        {
            string S="";
            forl(j,i,min(i+3,n))
            {
                S+=s[j];
                if(!mp[S])
                    mp[S]=++k;
                mp2[mp[S]]=S;
                G[mp[S]].pb({i,j});
                sz[mp[S]]++;
            }
        }
        forl(i,1,k)
            if(sz[i]>=sq)
                big.pb(i),
                visbig[i]=1,
                bigmp[i]=++ID;
        forl(i,1,(ll)big.size())
            forl(j,1,k)
                ans[i][j]=1e9;
        Init();
        forl(_,1,q)
        {
            cin>>x>>y;
            ll id1=mp[x],id2=mp[y];
            if(!id1 || !id2)
            {
                cout<<-1<<endl;
                continue;
            }
            if(visbig[id1]+visbig[id2]==0)
            {
                ll L=-1,szm=(ll)G[id2].size()-1;
                ll len=1e18;
                for(auto i:G[id1])
                {
                    while(L<szm && G[id2][L+1].y<=i.y)
                        L++;
                    if(L!=-1)
                        Min(len,max(G[id2][L].y,i.y)-min(i.x,G[id2][L].x)+1);
                    if(L<szm)
                        Min(len,max(G[id2][L+1].y,i.y)-min(i.x,G[id2][L+1].x)+1);
                }
                if(len==1e18)
                    len=-1;
                cout<<len<<endl;
            }
            else
            {
                ll A=1e9;
                if(visbig[id1]+visbig[id2]==2)
                    A=min(ans[bigmp[id1]][id2],ans[bigmp[id2]][id1]);
                else if(visbig[id1])
                    A=ans[bigmp[id1]][id2];
                else
                    A=ans[bigmp[id2]][id1];
                if(A>=1e9)
                    A=-1;
                cout<<A<<endl;
            }
        }
    }
    int main()
    {
    	Init();
    //    freopen("tst.txt","r",stdin);
    //    freopen("sans.txt","w",stdout);
        IOS;
        _t_=1;
       // cin>>_t_;
        while(_t_--)
            solve();
        QwQ;
    }
    
    • 1

    信息

    ID
    1355
    时间
    4000ms
    内存
    256MiB
    难度
    5
    标签
    (无)
    递交数
    5
    已通过
    2
    上传者