题意:给定两个串\(S\)和\(T\),定义\(R_i\)为在\(s_i\)和\(s_{i+1}\)之间插入\(T\)串得到的字符串。\(i \in [0,|S|]\)
有\(Q\)次询问,形如\((l,r,k,x,y)\),求满足 \(l \leq i \leq r\) 且 \(x\) \(\leq\) \(i\) mod \(k\) \(\leq y\) 的所有\(i\)中,字典序最小的\(i\)。
\(|S|,|T|,Q \leq 10^5\)
题解:首先需要解决排序问题。我们可以对\(S + T\)建立后缀数组,求lcp。然后把1到n排个序。
比较\(i\)和\(j\)时,分两个串的\(T\)串部分是否相交讨论,相当于将两个串划成了五段,分别比较大小即可。
然后考虑这个奇怪的对\(i\)的限制。
发现所有合法的\(i\)都可以写成\(a+pk\)的形式,这样,所有合法的\(i\)可以看做是\(a\)轴,\(p\)轴的平面直角坐标系下的一个矩形。
由于矩形面积是\(O(n)\)的,而其边长的较小值不会超过\(\sqrt{n}\),所以我们只要能快速求出一行或一列的解,就能在\(O(\sqrt{n})\)的时间内解决单个问题了。
因此,我们进行根号分治。
对于较大的\(k\),我们枚举\(p\),对于连续的一段\([x+pk,y+pk]\),可以用st表预处理做到\(O(1)\)查询。
对于较小的\(k\),我们将所有询问离线下来,对于每个\(k\),每个\(a\),我们都建立一个st表,进行快速查询。由于\(k,a\)是\(\sqrt n\)级别的,所以st表最多处理\(n \sqrt n\)个元素,时间复杂度是\(O(n \sqrt n logn)\)。
代码:
#include
using namespace std;
#define re register int
#define F(x,y,z) for(re x=y;x<=z;x++)
#define FOR(x,y,z) for(re x=y;x>=z;x--)
typedef long long ll;
#define I inline void
#define IN inline int
#define C(x,y) memset(x,y,sizeof(x))
#define STS system("pause")
templateI read(D &res){
res=0;register D g=1;register char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')g=-1;
ch=getchar();
}
while(isdigit(ch)){
res=(res<<3)+(res<<1)+(ch^48);
ch=getchar();
}
res*=g;
}
const int N=316,Mx=200000;
char s[101000],t[101000];
int a[101000],b[101000],c[202000];
struct P{
int l,r,k,x,y,id;
friend bool operator < (P a,P b){return a.ky)swap(x,y);x++;
re ln=lg[y-x+1];
return min(f[x][ln],f[y-(1<y)swap(x,y),res=1;
if(x+m>y){
cp=ques_lcp(n+1,x+1);
// cout<<"!"<y)return -1;
// cout<<"@"<k)tp[++tot]=sa[i]-k;
F(i,1,num)buc[i]=0;
F(i,1,len)buc[rk[i]]++;
F(i,1,num)buc[i]+=buc[i-1];
FOR(i,len,1)sa[buc[rk[tp[i]]]--]=tp[i],tp[i]=0;
swap(rk,tp);rk[sa[1]]=tot=1;
F(i,2,len)rk[sa[i]]=(tp[sa[i-1]]==tp[sa[i]]&&tp[sa[i-1]+k]==tp[sa[i]+k])?tot:++tot;
if(tot==len)break;
num=tot;
}
re k=0;
F(i,1,len){
if(rk[i]==1)continue;
if(k)k--;
re p=sa[rk[i]-1];
while(c[i+k]==c[p+k])k++;
hei[rk[i]]=k;
}
F(i,1,len)f[i][0]=hei[i];
F(j,1,lg[len])F(i,1,len-(1<=x)ans[p[i].id]=ckmin(ans[p[i].id],ques_min(max(0,(p[i].l-x+w-1)/w),(p[i].r-x)/w));
}
// cout<<"!"<>1]+1;
F(i,1,q){
read(p[i].l);read(p[i].r);read(p[i].k);read(p[i].x);read(p[i].y);p[i].id=i;ans[i]=-1;
}
sort(p+1,p+1+q);
build_sa();
// while(1){
// int x,y;read(x);read(y);cout<N){
F(j,(p[i].l-p[i].x)/p[i].k,(p[i].r-p[i].x+p[i].k-1)/p[i].k){
L=max(p[i].l,j*p[i].k+p[i].x),R=min(p[i].r,j*p[i].k+p[i].y);
if(L<=R)ans[p[i].id]=ckmin(ans[p[i].id],ques(L,R));
}
continue;
}
if(p[i].k==p[i+1].k)continue;
solve(L,i,p[i].k);L=i+1;
}
F(i,1,q)printf("%d ",ans[i]);
return 0;
}
/*
arjqmnlntv odkjqehmil 10
5 10 8 0 5
4 10 6 3 4
7 9 7 2 2
0 8 1 0 0
4 7 1 0 0
0 7 7 0 1
2 8 2 1 1
3 5 8 0 0
5 9 2 0 1
1 7 4 1 3
swquopwbur wociakyvje 10
4 8 9 5 6
1 9 5 1 3
4 6 10 4 6
5 7 4 2 3
7 9 8 1 5
7 10 6 0 2
5 8 10 5 7
0 0 6 0 4
3 6 3 2 2
0 6 3 2 2
*/