首页 > 其他分享 >Codeforces 1909G - Pumping Lemma

Codeforces 1909G - Pumping Lemma

时间:2023-12-26 10:55:37浏览次数:45  
标签:le const int Codeforces hs2 Lemma 1ll hs1 1909G

这个题思考角度很多,做法也很多。这里介绍一种 @asmend 和我讲的做法。

设 \(d=m-n\),那么我们枚举 \(|x|=i,|y|=j\),设 \(s,t\) 的 LCP 长为 \(l_1\),LCS 长为 \(l_2\),那么可以得到这组 \((i,j)\) 合法的充要条件是:

  • \(i\le l_1\)
  • \(m-i-j-d\le l_2\)。
  • \(d\bmod j=0\)。
  • \(t[i,i+d-1]=t[i+j,i+j+d-1]\)。

考虑第四条限制,我们将所有长度为 \(d\) 的子串的哈希值排序,这样对于每种子串,我们可以知道其出现的位置 \(p_1,p_2,\cdots,p_c\)。考虑 occurrence 序列的一个性质:对于极长的满足 \(p_{l+1}-p_l\le d,p_{l+2}-p_{l+1}\le d,\cdots,p_r-p_{r-1}\le d\) 的连续段 \([l,r]\),必然有 \(p_{l+1}-p_l=p_{l+2}-p_{l+1}=\cdots=p_r-p_{r-1}\),这个可以用 WPL 证明。这样考虑对每个这样的连续段统计贡献,设等差数列的公差为 \(t\),长度为 \(c\),因为是等差数列,因此这个连续段内部可能出现的 \(j\) 只有 \(t,2t,\cdots,(c-1)t\) 这 \(O(c)\) 种,枚举之,那么第一、二条限制的作用是将 \(i\) 限制在一个区间内,这样相当于求等差数列中在这个区间内的数的个数,这容易 \(O(1)\)。因为 \(\sum c=O(n)\),所以后面复杂度为线性。复杂度瓶颈在排序,如果使用三个与 \(n\) 同阶的质数作为哈希模数并桶排则可以线性。但我直接 sort 以 1996ms 卡了过去就没管了(

const int MAXN=1e7;
const int MOD1=1e9+21;
const int MOD2=1e9+33;
const int BS1=191;
const int BS2=193;
int qpow(int x,int e,int mod){int ret=1;for(;e;e>>=1,x=1ll*x*x%mod)if(e&1)ret=1ll*ret*x%mod;return ret;}
char s[MAXN+5],t[MAXN+5];int n,m,d,pw1,pw2;
struct _hash{
	int hs1,hs2,pos;
	_hash(){hs1=hs2=pos=0;}
	void append(int x){
		hs1=(1ll*hs1*BS1+x)%MOD1;
		hs2=(1ll*hs2*BS2+x)%MOD2;
	}
	void del(int x){
		hs1=(hs1+1ll*(MOD1-pw1)*x)%MOD1;
		hs2=(hs2+1ll*(MOD2-pw2)*x)%MOD2;
	}
	friend bool operator <(const _hash &X,const _hash &Y){
		if(X.hs1!=Y.hs1)return X.hs1<Y.hs1;
		if(X.hs2!=Y.hs2)return X.hs2<Y.hs2;
		return X.pos<Y.pos;
	}
	friend bool operator ==(const _hash &X,const _hash &Y){
		return (X.hs1==Y.hs1&&X.hs2==Y.hs2);
	}
}a[MAXN+5],cur;
int limL,limR;ll res=0;
int calc(int l,int r,int stp,int rem){
	if(l>r)return 0;
	return (r-rem+stp)/stp-(l-1-rem+stp)/stp;
}
void work(int l,int r){
	for(int i=l;i<r;i++)res+=(a[i+1].pos-a[i].pos==d);
	for(int L=l,R;L<=r;L=R+1){
		if(a[L].pos>limR)break;
		R=L;while(R<r&&a[R+1].pos-a[R].pos<d)++R;
		if(L!=R){
			int d0=a[L+1].pos-a[L].pos;
			for(int j=1;j<=R-L;j++)if(d%(j*d0)==0){
				int _R=limR,_L=limL-j*d0;
				res+=calc(max(_L,a[L].pos),min(_R,a[R-j].pos),d0,a[R].pos%d0);
			}
		}
	}
}
int main(){
	scanf("%d%d%s%s",&n,&m,s+1,t+1);d=m-n;
	pw1=qpow(BS1,d,MOD1);pw2=qpow(BS2,d,MOD2);
	for(int i=1;i<=m;i++){
		cur.append(t[i]);
		if(i>d)cur.del(t[i-d]);
		if(i>=d)a[i-d+1]=cur,a[i-d+1].pos=i-d+1;
	}
	sort(a+1,a+m-d+2);
//	for(int i=1;i<=m-d+1;i++)printf("(%d,%d,%d) %d\n",a[i].hs1,a[i].hs2,a[i].hs3,a[i].pos);
	int len1=0,len2=0;
	while(len1<n&&s[len1+1]==t[len1+1])++len1;
	while(len2<n&&s[n-len2]==t[m-len2])++len2;
	limR=len1+1;limL=m-len2-d+1;
	for(int l=1,r;l<=m-d+1;l=r){
		r=l;while(r<=m-d+1&&a[r]==a[l])++r;
		work(l,r-1);
	}
	printf("%lld\n",res);
	return 0;
}

标签:le,const,int,Codeforces,hs2,Lemma,1ll,hs1,1909G
From: https://www.cnblogs.com/tzcwk/p/Codeforces-1909G.html

相关文章

  • Codeforces1917F - Construct Tree
    Codeforces1917F-ConstructTreeProblems给一个长度为\(n\)的序列\(l\)和\(d\)。要求判断是否可以构造出一颗节点数为\(n+1\)的树,满足\(l\)的每一个元素唯一对应为一条边的长度,并使整棵树的直径长度恰好为\(d\)。Solution不妨令\(l_1\lel_2\le\cdots\lel_......
  • CodeForces 1906K Deck-Building Game
    洛谷传送门CF传送门UNR#2黎明前的巧克力。枚举两个人选的卡的并集\(S\),那么当\(\bigoplus\limits_{i\inS}a_i=0\)时\(S\)有贡献\(2^{|S|}\)。考虑将\(2^{|S|}\)分摊到每个元素上,也就是每个元素有\(2\)的贡献,然后把这些贡献乘起来。所以题目其实是想让我们算......
  • Codeforces1917E - Construct Matrix
    Codeforces1917E-ConstructMatrix首先考虑因为\(n\)为偶数,所以\(k\)为奇数时不可能满足条件。其次,如果\(4|k\),那么实际上在矩阵中一直放\(2\times2\)的全为\(1\)的矩阵就可以了。随后,如果\(k\equiv2\mod4\),那么可以证明如果\(k\ne2\landk\nen^2-2\),......
  • Codeforces Round 917 (Div. 2)
    基本情况A题秒了,B题卡了一年。B.EraseFirstorSecondLetterProblem-B-Codeforces卡题分析两方面原因没有变通,一开始的思路是公式算出总字串数再想办法找重复的减掉,但搞了一个小时都不可行,应该早点换成正着来找的思路。没有更深入的分析样例。最后虽然出来了,......
  • codeforces刷题(1100):1907C_div3
    C、RemovalofUnattractivePairs跳转原题点击此:该题地址1、题目大意  给定一个字符串,可以删除相邻的两个不相等的字符。问你删除后能得到最小的字符串长度为多少。2、题目解析  因为只要两个不相等的字符相邻就能消除,所以只需要找到数量最多的字符,只要它的数量比其它字......
  • CodeForces 1909E Multiple Lamps
    洛谷传送门CF传送门感觉这个题比较难蚌。发现按\(1\simn\)最后可以把\(1\simn\)中的所有平方数点亮。所以\(n\ge20\)就直接输出\(1\simn\)。考虑\(n\le19\)。猜测合法的方案(即按完后亮灯数\(\le\left\lfloor\frac{n}{5}\right\rfloor\)的方案,不考虑\((......
  • CodeForces 1909D Split Plus K
    洛谷传送门CF传送门设最后每个数都相等时为\(t\)。那么一次操作变成了合并两个数\(x,y\),再增加\(x+y-k\)。于是每个\(a_i\)可以被表示成\(b_it-(b_i-1)k\)的形式,化简得\(a_i-k=b_i(t-k)\)。因为\(t-k\)对于每个\(i\)都相同,又因为我们的目标是......
  • CodeForces 1909F2 Small Permutation Problem (Hard Version)
    洛谷传送门CF传送门感觉这个题还是挺不错的。考虑F1。考察\(a_i\)差分后的意义,发现\(a_i-a_{i-1}\)就是\((\sum\limits_{j=1}^{i-1}[p_j=i])+p_i\lei\)。考虑将其转化为棋盘问题。在\((i,p_i)\)放一个车,那么\(a_i-a_{i-1}\)就是\((1,i)\sim......
  • Codeforces 1900E Transitive Graph
    考虑题目的限制条件:存在$a\tob,b\toc$的边,就会有$a\toc$的边。考虑$p_{1\simk}$,满足这$k$个点按顺序组成了一个环且无重点。那么$p_1\top_2,p_2\top_3$,就有$p_1\top_3$,又有$p_3\top_4$,所以有$p_1\top_4$。以此类推,会发现$\foralli,j\in[1,k],i\not......
  • Codeforces Round 651 (Div. 2)C. Number Game(数学思维数论)
    C.NumberGame我们考虑那些状态是必胜态我的回合时n为奇数(除1外),直接除以n则必胜下面偶数的情况稍复杂偶数我们能进行的操作只有除以一个奇数,需要考虑怎么把当前状态变为对手的必败态偶数一定含2的因子,\(n=2^k*q,q为奇数\)当\(k=1时如果q\)是一个质数那么只能除一次q这样......