「杂题乱刷2」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;
}

浙公网安备 33010602011771号