「杂题乱刷2」CF444D DZY Loves Strings

题目链接

CF444D DZY Loves Strings

解题思路

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

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

那么对于每一个询问,如果两个字符串有至少一个字符串出现次数是 \(> \sqrt{m}\) 的,那么此时我们已经预处理过了,直接输出答案即可,时间复杂度 \(O(1)\)。否则,如果两个字符串出现次数都是 \(\le \sqrt{m}\) 的,那么此处我们直接枚举第一个字符串所在的位置,对于第二个字符串直接双指针维护即可,此处时间复杂度 \(\sqrt{m}\),此处最劣时间复杂度为 \(O(q \sqrt{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;
}
posted @ 2025-04-09 15:13  wangmarui  阅读(22)  评论(0)    收藏  举报