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

举报
Fivecc 发表于 2022/08/05 22:51:37 2022/08/05
【摘要】                              「LibreOJ β Round #7」匹配字符串           &...

 


                           「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 代码:


  
  1. #include<stdio.h>
  2. #include<string.h>
  3. typedef long long ll;
  4. #define mod 65537
  5. ll m,n;
  6. ll f[6005],g[6005],tp[6005];
  7. void mul(ll *a,ll *b)
  8. {
  9. for(int i=0;i<=2*m;i++) tp[i]=0;
  10. for(int i=0;i<m;i++)
  11. for(int j=0;j<m;j++)
  12. tp[i+j]=(tp[i+j]+a[i]*b[j])%mod;
  13. for(int i=2*m-2;i>=m;i--)
  14. {
  15. for(int j=0;j<m;j++)
  16. tp[i-m+j]=(tp[i-m+j]+tp[i])%mod;
  17. tp[i]=0;
  18. }
  19. for(int i=0;i<m;i++) a[i]=tp[i];
  20. }
  21. void ksm1()
  22. {
  23. while(n)
  24. {
  25. if(n&1)mul(g,f);
  26. mul(f,f);
  27. n>>=1;
  28. }
  29. }
  30. void f1()
  31. {
  32. f[1]=1; g[0]=1;
  33. ksm1();
  34. ll s=1,ans=0;
  35. for(int i=0;i<m;i++) ans=(ans+s*g[i])%mod,s=s*2%mod;
  36. printf("%lld\n",(ans%mod+mod)%mod);
  37. }
  38. ll fac[65538],inv[65538];
  39. ll C(ll n,ll m)
  40. {
  41. if(m>n) return 0;
  42. if(n>=mod) return C(n/mod,m/mod)*C(n%mod,m%mod)%mod;
  43. else return fac[n]*inv[m]*inv[n-m]%mod;
  44. }
  45. ll ksm2(ll x,ll k)
  46. {
  47. ll s=1;
  48. while(k)
  49. {
  50. if(k&1) s=s*x%mod;
  51. x=x*x%mod;
  52. k>>=1;
  53. }
  54. return s;
  55. }
  56. ll calc(ll n1)
  57. {
  58. ll ans=0,pw2=ksm2(2,n1),iv=ksm2(ksm2(2,m+1),mod-2);
  59. int lim=n1/(m+1);
  60. for(int i=0;i<=lim;++i)
  61. {
  62. if(i&1) ans-=pw2*C(n1-i*m,i);
  63. else ans+=pw2*C(n1-i*m,i);
  64. pw2=pw2*iv%mod;
  65. }
  66. return (ans%mod+mod)%mod;
  67. }
  68. void f2()
  69. {
  70. fac[0]=inv[0]=1;
  71. for(int i=1;i<mod;i++) fac[i]=fac[i-1]*i%mod;
  72. inv[mod-1]=ksm2(fac[mod-1],mod-2);
  73. for(int i=mod-2;i>=1;i--) inv[i]=inv[i+1]*(i+1)%mod;
  74. printf("%lld\n",(calc(n+1)-calc(n)+mod)%mod);
  75. }
  76. int main()
  77. {
  78. scanf("%lld%lld",&n,&m);
  79. if(m<=3000) f1();
  80. else f2();
  81. return 0;
  82. }

 

 

文章来源: fivecc.blog.csdn.net,作者:Five-菜鸟级,版权归原作者所有,如需转载,请联系作者。

原文链接:fivecc.blog.csdn.net/article/details/83016489

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。