luogu P4022 [CTSC2012]熟悉的文章

题面传送门
看到字符串子串匹配啪的一下很快啊一个SAM扔上去了
先把\(M\)个串的SAM建出来,发现其实不用广义SAM,隔一个#插就好了。
然后对于每个询问串就可以在SAM上先刨除每个\(i\)结尾在模式串中最长匹配多少。
显然L有单调性所以直接二分然后\(O(n^2)\)dp就可以得到答案了。
又有显然的每个点最左边能匹配的单调不降,所以可以上单调队列维护当前\(dp_i-i\)就可以做到\(O(nlogn)\)了。
code:

#include<bits/stdc++.h>
#define I inline
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define re register
#define RI re int
#define ll long long
#define db double
#define lb long db
#define N 1100000
#define M 300000
#define mod 1000000007
#define Mod (mod-1)
#define eps (1e-5)
#define U unsigned int
#define it iterator
#define Gc() getchar()
#define Me(x,y) memset(x,y,sizeof(x))
#define d(x,y) (m*(x-1)+(y))
#define R(n) (rand()*rand()%(n)+1)
#define Pc(x) putchar(x)
using namespace std;
int n,m,Q[N+5],H,T,dp[N+5],L[N+5],k,l,r,mid;char S[N+5];
namespace SAM{
	int cnt=1,son[N+5][3],link[N+5],len[N+5],p,La=1,q;I void Ins(char c){
		c^'#'?c-='0':c=2;;p=La;La=++cnt;len[La]=len[p]+1;while(p&&!son[p][c]) son[p][c]=La,p=link[p];if(!p){link[La]=1;return;}
		q=son[p][c];if(len[q]==len[p]+1)link[La]=q;else{
			link[++cnt]=link[q];link[q]=link[La]=cnt;len[cnt]=len[p]+1;memcpy(son[cnt],son[q],sizeof(son[q]));
			while(p&&son[p][c]==q) son[p][c]=cnt,p=link[p];
		}
	}
	I int check(int mid){
		RI i;H=1;T=0;for(i=1;i<=k;i++){
			if(i>=mid){while(H<=T&&dp[Q[T]]-Q[T]<=dp[i-mid]-(i-mid)) T--;Q[++T]=i-mid;}while(H<=T&&Q[H]<i-L[i]) H++;dp[i]=dp[i-1];H<=T&&(dp[i]=max(dp[i],dp[Q[H]]+(i-Q[H])));
		}/*printf("%d %d\n",mid,dp[k]);*/return dp[k]>=k*0.9;
	}
	I void Solve(){
		RI i;scanf("%s",S+1);k=strlen(S+1);p=1;q=0;for(i=1;i<=k;i++) {while(p&&!son[p][S[i]-'0']) p=link[p],q=len[p];if(!p) p=1,q=0;else p=son[p][S[i]-'0'],q++;L[i]=q;/*printf("%d %d\n",p,q);*/}
		l=1;r=k+1;while(l+1<r) mid=l+r>>1,(check(mid)?l:r)=mid;printf("%d\n",l);
	}
}
int main(){
	freopen("1.in","r",stdin);
	RI i;scanf("%d%d",&n,&m);while(m--)for(scanf("%s",S+1),SAM::Ins('#'),k=strlen(S+1),i=1;i<=k;i++) SAM::Ins(S[i]);while(n--)SAM::Solve();
}
上一篇:noip2021 训练4 做题记录


下一篇:Failed to create pod sandbox: rpc error: code = Unknown desc = [failed to set up sandbox container.