A. 卷

发现乘积足以爆 \(long\) \(long\),但是数据随机,可以略忽略精度问题

一个快速降低数的级别的方法是取对数,由于有性质 \(log(x * y)=logx+logy\),合并时运算会很方便,于是转化成加和型最大独立集问题


B. 简单题

观察发现对于每个奇数,其 \(2\) 倍放在另一个集合,\(4\) 倍放在当前集合,以此类推

那么对于一条偶数长度的链,一定一半放在第一个集合,另一半放在第二个集合,对答案贡献乘 \(2\)

对于奇数长度的链,一定分成 \(len\) 和 \(len+1\) 两部分,那么这样最终答案一定有可行区间 \([l,r]\),那么多出 \(l\) 的部分一定是若干个奇数链造成的,而奇数链又是自由组合,设总数为 \(tot\),答案为 \(\binom{tot}{m-l}\)

发现组合数数过大,模数很小,可以用 \(lucas\) 定理计算

对于计算奇偶链的个数,考虑枚举链长,这是 \(log\) 级别的,那么长度的 \(k\) 的链的起点范围为 \(\displaystyle[\frac{n}{2^{k-1}}+1,\frac{n}{2^k}]\),因为这个不分奇数,得除以 \(2\)

代码实现
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define int long long
  4. const int maxn=5005;
  5. const int maxm=11000025;
  6. const int mod=10000019;
  7. int n,q,x,tot1,tot2,l,r,frac[maxm],inv[maxm],ans,ans1,len;
  8. int po(int a,int b=mod-2){
  9. int ans=1;
  10. while(b){
  11. if(b&1)ans=ans*a%mod;
  12. a=a*a%mod;
  13. b>>=1;
  14. }
  15. return ans;
  16. }
  17. int read(){
  18. int x=0,f=1;
  19. char ch=getchar();
  20. while(!isdigit(ch)){
  21. if(ch=='-')f=-1;
  22. ch=getchar();
  23. }
  24. while(isdigit(ch)){
  25. x=x*10+ch-48;
  26. ch=getchar();
  27. }
  28. return x*f;
  29. }
  30. void pre(){
  31. frac[0]=1;
  32. for(int i=1;i<=mod-1;i++)frac[i]=frac[i-1]*i%mod;//,cout<<frac[i]<<" ";
  33. inv[mod-1]=po(frac[mod-1]);
  34. // cout<<frac[mod]<<" "<<inv[mod]<<endl;
  35. for(int i=mod-2;i>=0;i--)inv[i]=(i+1)*inv[i+1]%mod;//,cout<<inv[i]<<" ";
  36. return ;
  37. }
  38. int C(int n,int m){
  39. if(n<m)return 0;
  40. if(n==m)return 1;
  41. return frac[n]*inv[m]%mod*inv[n-m]%mod;
  42. }
  43. int lucas(int x,int y){
  44. // cout<<"hhh "<<x<<" "<<y<<endl;
  45. if(x==y)return 1;
  46. if(x<y)return 0;
  47. if(x<mod&&y<mod)return C(x,y);
  48. return lucas(x/mod,y/mod)*C(x%mod,y%mod)%mod;
  49. }
  50. signed main(){
  51. // cout<<po(2);
  52. n=read();
  53. q=read();
  54. pre();
  55. // cout<<C(6,2)<<endl;
  56. len=log2(n)+1;
  57. // cout<<len<<endl;
  58. for(int i=1;i<=len;i++){
  59. // cout<<i<<endl;
  60. int po1=pow(2,i-1);
  61. int po2=pow(2,i);
  62. int up=n/po1;
  63. int down=n/po2+1;
  64. if(down&1)down--;
  65. if(up&1)up++;
  66. int num=(up-down)/2;
  67. if(i&1){
  68. tot1+=num;
  69. }
  70. else tot2+=num;
  71. l+=num*(i/2);
  72. }
  73. r=l+tot1;
  74. // cout<<tot1<<" "<<tot2<<" "<<l<<" "<<r<<endl;
  75. ans1=po(2,tot2);
  76. // cout<<"ppp "<<endl;
  77. for(int i=1;i<=q;i++){
  78. x=read();
  79. if(x<l||x>r){
  80. puts("0");
  81. continue;
  82. }
  83. ans=ans1*lucas(tot1,x-l)%mod;
  84. printf("%d\n",ans);
  85. }
  86. return 0;
  87. }

C. 粉丝

这道题本质是自然数拆分,运用根号分治优化

首先自然数拆分有两种 \(dp\) 方法:

设 \(f[i][j]\) 表示 \(dp\) 到 \(i\) 这个数和为 \(j\) 的方案数,\(f[i][j]=f[i-1][j]+f[i][j-i]\)

\(g[i][j]\) 表示分成了 \(i\) 个数字,和为 \(j\) 的方案数

发现两种 \(dp\) 单独做都是 \(n^2\) 的

但是观察第一种 \(dp\) 的状态是 \(dp\) 到 \(i\) 这个数,值域越小复杂度越低

第二种状态是分成 \(i\) 个数,值域越大复杂度越低

于是在 \(\sqrt n\) 处分治,值域小的部分用第一种,大的部分用第二种,总复杂度为 \(n\sqrt n\)

注意第二种 \(dp\) 其实是每个选了了的数都已经以 \(sq\) 为基准了,那么实际的总和需要加上 \(num*sq\),这个合并时用 \(num\) 记录

代码实现
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define int long long
  4. const int maxn=1e5+5;
  5. int x,y,n,mod,f[maxn],g[maxn],sum[maxn],sq,ans;
  6. int dp(int limit){
  7. memset(f,0,sizeof f);
  8. memset(g,0,sizeof g);
  9. memset(sum,0,sizeof sum);
  10. ans=0;
  11. f[0]=1;
  12. sq=max((int)sqrt(n),limit);
  13. for(int i=limit;i<sq;i++){
  14. for(int j=i;j<=n;j++){
  15. f[j]+=f[j-i];
  16. f[j]%=mod;
  17. }
  18. }
  19. g[0]=1;
  20. sum[0]=1;
  21. for(int i=1;i<=n/sq;i++){
  22. int t=i*sq;
  23. for(int j=i;j+t<=n;j++){
  24. g[j]=(g[j]+g[j-i])%mod;
  25. }
  26. for(int j=0;j+t<=n;j++){
  27. sum[j+t]+=g[j];
  28. sum[j+t]%=mod;
  29. }
  30. }
  31. for(int i=0;i<=n;i++){
  32. ans=(ans+f[i]*sum[n-i]%mod)%mod;
  33. }
  34. return ans;
  35. }
  36. signed main(){
  37. cin>>x>>y>>n>>mod;
  38. cout<<(dp(x)-dp(y+1)+mod)%mod;
  39. return 0;
  40. }

D. 字符串

首先可以把两端本身就对称的部分砍掉,作为 \(A\) 和 \(E\) 的部分,然后中间找一个回文串进行扩展

会出现一下两种情况

那么找相同串的情况可以翻转一次接在最后做一遍 \(KMP\),由于中间插入了一个特殊字符,\(KMP\) 后不会跨边界

代码实现
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int maxn=2e7+5;
  4. char c[maxn],a[maxn],b[maxn];
  5. int n,cnt1,tot,len,cnt,p[maxn],ans,nxt[maxn],mx[maxn];
  6. void manacher(){
  7. memset(p,0,sizeof p);
  8. for(int t=1,mid=0,r=0;t<=cnt;t++){
  9. if(t<=r)p[t]=min(p[mid*2-t],r-t+1);
  10. while(a[t+p[t]]==a[t-p[t]])p[t]++;
  11. if(t+p[t]>r)r=p[t]+t-1,mid=t;
  12. }
  13. return ;
  14. }
  15. void init(){
  16. for(int i=1;i<=len/2;i++){
  17. if(c[i]==c[len-i+1])tot++;
  18. else break;
  19. }
  20. n=len-tot*2;
  21. for(int i=1;i<=n;i++){
  22. c[i]=c[i+tot];
  23. }
  24. return ;
  25. }
  26. void pre(){
  27. a[0]='?';
  28. a[cnt=1]='#';
  29. for(int i=1;i<=n;i++){
  30. a[++cnt]=c[i];
  31. a[++cnt]='#';
  32. }
  33. }
  34. void kmp(){
  35. memset(nxt,0,sizeof nxt);
  36. memset(mx,0,sizeof mx);
  37. for(int i=cnt1-1,j=0;i>=1;i--){
  38. while(j&&b[i]!=b[cnt1-j])j=nxt[j];
  39. if(b[i]==b[cnt1-j])j++;
  40. nxt[i]=j;
  41. }
  42. for(int i=n;i>=1;i--){
  43. mx[i]=max(mx[i+1],nxt[i]);
  44. }
  45. return ;
  46. }
  47. void pre1(){
  48. cnt1=n;
  49. for(int i=1;i<=n;i++)b[i]=c[i];
  50. b[++cnt1]='$';
  51. for(int i=n;i>=1;i--){
  52. b[++cnt1]=c[i];
  53. }
  54. return ;
  55. }
  56. void solve(){
  57. for(int i=1;i<=cnt;i++){
  58. int posl=(i-p[i])/2;
  59. int posr=(i+p[i])/2;
  60. if(nxt[posr]<=posl)ans=max(ans,p[i]-1+nxt[posr]*2);
  61. if(mx[posr]>=posl)ans=max(ans,p[i]-1+posl*2);
  62. }
  63. return ;
  64. }
  65. void work(){
  66. pre();
  67. manacher();
  68. pre1();
  69. kmp();
  70. solve();
  71. return ;
  72. }
  73. int main(){
  74. scanf("%s",c+1);
  75. len=strlen(c+1);
  76. init();
  77. if(tot==n/2){
  78. cout<<n;
  79. return 0;
  80. }
  81. work();
  82. reverse(c+1,c+n+1);
  83. work();
  84. cout<<ans+tot*2;
  85. return 0;
  86. }

noip模拟42的更多相关文章

  1. Noip模拟42 2021.8.17

    T1 卷 一看跟没有上司的舞会一样,直接敲了然后试个自己造的样例对了就跑了... 然而把它想简单了,乘积取模,还能比大小吗????? 显然不能 所以直接让对数的加和跟着$dp$直接一起跑,比大小的都用 ...

  2. [考试总结]noip模拟42

    开始给了一个简单的题目,但我还是没有珍惜. 一个简简单单的树形 \(dp\),然而因为取模却不知道该如何比较大小.. 其实可以取 \(log\),然后我就梦中惊坐起,然后想到了魔法少女lbw 淦 然后 ...

  3. NOIP模拟 1

    NOIP模拟1,到现在时间已经比较长了.. 那天是6.14,今天7.18了 //然鹅我看着最前边缺失的模拟1,还是终于忍不住把它补上,为了保持顺序2345重新发布了一遍.. #   用  户  名   ...

  4. NOIP模拟17.9.22

    NOIP模拟17.9.22 前进![问题描述]数轴的原点上有一只青蛙.青蛙要跳到数轴上≥

  5. NOIP 模拟4 T2

    本题属于二和一问题 子问题相互对称 考虑对于问题一:知a求b 那么根据b数组定义式 显然能发现问题在于如何求dis(最短路) 有很多算法可供选择 dijsktra,floyed,bfs/dfs,spf ...

  6. 2021.9.17考试总结[NOIP模拟55]

    有的考试表面上自称NOIP模拟,背地里却是绍兴一中NOI模拟 吓得我直接文件打错 T1 Skip 设状态$f_i$为最后一次选$i$在$i$时的最优解.有$f_i=max_{j<i}[f_j+a ...

  7. NOIP模拟赛20161022

    NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...

  8. contesthunter暑假NOIP模拟赛第一场题解

    contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...

  9. NOIP模拟赛 by hzwer

    2015年10月04日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...

随机推荐

  1. 面试官:展开说说,Spring中Bean对象是如何通过注解注入的?

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 章节目录(手写Spring,让你了解更多) [x] 第 01 章:开篇介绍,我要带你撸 Spr ...

  2. Android 开发学习进程0.33 横竖屏切换

    安卓横竖屏大多数已经在manifest文件中将activity使用android:screenOrientation="portrait"属性写死,如简单的界面切换可直接更改为&q ...

  3. Java架构师-十项全能学习笔记(1)

    Java架构师-十项全能学习笔记(1) @Configuration @EnableStateMachine public class OrderStateMachineConfig extends ...

  4. MySQL 创建高性能索引

    索引是存储引擎用于快速找到记录的一种数据结构.除了加速查找,索引在其他方面也有一些有用的属性.索引对于良好的性能非常关键.尤其是当表中的数据量越来越大时,索引对性能的影响愈发重要.在数据量较小且负载较 ...

  5. RHCE_DAY01

    shell概述 shell是一个程序,它连接了用户和Linux内核,它可以解释用户输入的命令传递给内核,让用户可以更加方便的使用Linux系统 shell 本身并不是内核的一部分,它只是站在内核的基础 ...

  6. rollup 开发环境搭建

    rollup 开发环境搭建 初始化项目使用lerna管理项目 使用npm init 初始化项目 npm init -y 安装lerna并初始化项目 npm install lerna --save-d ...

  7. FSM自动售货机 verilog 实现及 code 细节讲解

    1.题目: 饮料1.5 元, 可投入硬币1 元 0.5 元,输出饮料 零钱 2. 画出状态机. 3.仿真结果:coin=1 --> 0.5 元 coin=2-->1元 4.关键代码分析: ...

  8. Ubuntu系统Root用户无法登录

    默认 系统 root 登录 图形界面,出现 登录失败.解决方法如下: 1,登录普通用户, 打开终端执行命令, 使用su root或sudo -i切换到root用户(必须) su root 按照提示输入 ...

  9. Java之Cookie与Session

    Cookie.Session Cookie:服务端生成Cookie发给客户端用于认证 Session:服务端进行进行登记,每人有不同的Session session与cookie的区别 Cookie: ...

  10. DVWA(五):CSRF 全等级跨站请求伪造

    CSRF,全称Cross-site request forgery,翻译过来就是跨站请求伪造,是指利用受害者尚未失效的身份认证信息(cookie.会话等),诱骗其点击恶意链接或者访问包含攻击代码的页面 ...