首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >「LibreOJ β Round #7」匹配字符串

「LibreOJ β Round #7」匹配字符串

作者头像
Fivecc
发布2022-11-21 15:45:37
发布2022-11-21 15:45:37
21000
代码可运行
举报
文章被收录于专栏:前端ACE前端ACE
运行总次数:0
代码可运行

                           「LibreOJ β Round #7」匹配字符串

                                                 时间限制: 2 Sec  内存限制: 512 MB

题目描述

          对于一个 01 串(即由字符 0 和 1 组成的字符串)sss,我们称 sss 合法,当且仅当串 sss 的

          任意一个长度为 mmm 的子串 s′s's′,不为全 1 串。

          请求出所有长度为 nnn 的 01 串中,有多少合法的串,答案对 655376553765537 取模。

输入格式

输入共一行,包含两个正整数 n,mn,mn,m。

输出格式

输出共一行,表示所求的和对 655376553765537 取模的结果。

样例

样例输入 1

5 2

样例输出 1

13

样例解释 1

以下是所有合法的串:

00000 00001 00010 00100 00101 01000 01001 01010 10000 10001 10010 10100 10101

样例输入 2

2018 7

样例输出 2

27940

数据范围与提示

对于所有的数据,满足 1≤n,m≤687215739041\le n,m\le 687215739041≤n,m≤68721573904。

详细的数据限制及约定如下(留空表示和上述所有数据的约定相同):

Subtask #

分值

nnn

mmm

1

666

≤18\le 18≤18

≤18\le 18≤18

2

777

≤109\le 10^9≤10​9​​

≤2\le 2≤2

3

151515

≤106\le 10^6≤10​6​​

≤106\le 10^6≤10​6​​

4

101010

≤109\le 10^9≤10​9​​

≤50\le 50≤50

5

141414

≤109\le 10^9≤10​9​​

≤500\le 500≤500

6

151515

≤4295098369\le 4295098369≤4295098369

-

7

181818

≤17180393476\le 17180393476≤17180393476

-

8

151515

题目链接:http://118.24.30.237/problem.php?id=2991

https://loj.ac/problem/547

AC 代码:

代码语言:javascript
代码运行次数:0
运行
复制
#include<stdio.h>
#include<string.h>
typedef long long  ll;
#define  mod 65537
ll m,n;
ll f[6005],g[6005],tp[6005];
void mul(ll *a,ll *b)
{
	for(int i=0;i<=2*m;i++) tp[i]=0;
	for(int i=0;i<m;i++)
    for(int j=0;j<m;j++)
	 tp[i+j]=(tp[i+j]+a[i]*b[j])%mod;
	for(int i=2*m-2;i>=m;i--)
	{
		for(int j=0;j<m;j++)
			tp[i-m+j]=(tp[i-m+j]+tp[i])%mod;
		tp[i]=0;
	}
	for(int i=0;i<m;i++) a[i]=tp[i];
}
void ksm1()
{
	while(n)
	{
		if(n&1)mul(g,f);
		mul(f,f);
		n>>=1;
	}
}
void f1()
{
	f[1]=1; g[0]=1;
	ksm1();
	ll s=1,ans=0;
	for(int i=0;i<m;i++) ans=(ans+s*g[i])%mod,s=s*2%mod;
	printf("%lld\n",(ans%mod+mod)%mod);
}
ll fac[65538],inv[65538];

ll C(ll n,ll m)
{
	if(m>n) return 0;
	if(n>=mod) return C(n/mod,m/mod)*C(n%mod,m%mod)%mod;
	else return fac[n]*inv[m]*inv[n-m]%mod;
}
ll ksm2(ll x,ll k)
{
	ll s=1;
	while(k)
	{
		if(k&1) s=s*x%mod;
		x=x*x%mod;
		k>>=1;
	}
	return s;
}
ll calc(ll n1)
{
	ll ans=0,pw2=ksm2(2,n1),iv=ksm2(ksm2(2,m+1),mod-2);
	int lim=n1/(m+1);
	for(int i=0;i<=lim;++i)
	{
		if(i&1) ans-=pw2*C(n1-i*m,i);
		else ans+=pw2*C(n1-i*m,i);
		pw2=pw2*iv%mod;
	}
	return (ans%mod+mod)%mod;
}
void f2()
{
	fac[0]=inv[0]=1;
	for(int i=1;i<mod;i++) fac[i]=fac[i-1]*i%mod;
	inv[mod-1]=ksm2(fac[mod-1],mod-2);
	for(int i=mod-2;i>=1;i--) inv[i]=inv[i+1]*(i+1)%mod;
	printf("%lld\n",(calc(n+1)-calc(n)+mod)%mod);
}
int main()
{
	scanf("%lld%lld",&n,&m);
	if(m<=3000) f1();
	else f2();
	return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-10-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  •                            「LibreOJ β Round #7」匹配字符串
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档