NOI2007这道题人类进化更完全之后出现了新的做法

毕姥爷题解:

于是毕姥爷出了一道环形版的这题(test0814),让我们写这个做法

环形的情况下,k=5的时候是162阶递推。

求这个递推可以用BM算法

一个很好的介绍BM算法的博客

  1. //Achen
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<vector>
  7. #include<cstdio>
  8. #include<queue>
  9. #include<cmath>
  10. #include<set>
  11. #include<map>
  12. #define Formylove return 0
  13. #define For(i,a,b) for(int i=(a);i<=(b);i++)
  14. #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
  15. const int p=;
  16. typedef long long LL;
  17. typedef double db;
  18. using namespace std;
  19. int k;
  20.  
  21. template<typename T>void read(T &x) {
  22. char ch=getchar(); x=; T f=;
  23. while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
  24. if(ch=='-') f=-,ch=getchar();
  25. for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
  26. }
  27.  
  28. LL a[][];
  29. LL solve(int n) {
  30. LL rs=,f=;
  31. For(i,,n) For(j,,n) a[i][j]=(a[i][j]+p)%p;
  32. For(i,,n) {
  33. For(j,i+,n) {
  34. LL A=a[i][i],B=a[j][i],t;
  35. while(B) {
  36. t=A/B;
  37. For(k,i,n) a[i][k]=(a[i][k]-t*a[j][k]%p+p)%p;
  38. For(k,i,n) swap(a[i][k],a[j][k]);
  39. A%=B; swap(A,B); f=-f;
  40. }
  41. }
  42. rs=rs*a[i][i]%p;
  43. }
  44. if(f==-) rs=p-rs;
  45. return rs;
  46. }
  47.  
  48. #define ANS
  49. int main() {
  50. #ifdef ANS
  51. //freopen("shanghai.in","r",stdin);
  52. freopen("biao.out","w",stdout);
  53. #endif
  54. read(k);
  55. //printf("%d\n",500-2*k);
  56. int tot=;
  57. For(n,*k+,) {
  58. tot++;
  59. For(i,,n) For(j,i+,n) if(min(abs(i-j),n-abs(i-j))<=k) {
  60. a[i][i]++;
  61. a[j][j]++;
  62. a[i][j]--;
  63. a[j][i]--;
  64. }
  65. LL rs=solve(n-);
  66. printf("%lld,",rs);
  67. For(i,,n) For(j,,n) a[i][j]=;
  68. if(tot==) break;
  69. }
  70. Formylove;
  71. }

暴力程序(矩阵树定理)

对于每个k用上面这个暴力打表,再用下面这个模板得出递推(ps,BM算法n越大越精确,当k=5,n只取到200时会得出90多阶的递推而不是162阶)

  1. //Achen
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<vector>
  7. #include<cstdio>
  8. #include<queue>
  9. #include<cmath>
  10. #include<set>
  11. #include<map>
  12. #define Formylove return 0
  13. #define For(i,a,b) for(int i=(a);i<=(b);i++)
  14. #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
  15. const int N=,p=;
  16. typedef long long LL;
  17. typedef double db;
  18. using namespace std;
  19. int n,cnt,fail[N];
  20. vector<LL>f[N];
  21. LL a[N],delta[N];
  22.  
  23. template<typename T>void read(T &x) {
  24. char ch=getchar(); x=; T f=;
  25. while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
  26. if(ch=='-') f=-,ch=getchar();
  27. for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
  28. }
  29.  
  30. LL ksm(LL a,LL b) {
  31. LL rs=,bs=a%p;
  32. while(b) {
  33. if(b&) rs=rs*bs%p;
  34. bs=bs*bs%p;
  35. b>>=;
  36. }
  37. return rs;
  38. }
  39.  
  40. #define ANS
  41. int main() {
  42. #ifdef ANS
  43. freopen("biao.out","r",stdin);
  44. freopen("k4.out","w",stdout);
  45. #endif
  46. read(n);
  47. For(i,,n) read(a[i]);
  48. For(i,,n) {
  49. LL tp=;
  50. int up=f[cnt].size();
  51. For(j,,up-)
  52. tp=(tp+f[cnt][j]*a[i-j-]%p)%p;
  53. if(tp==a[i]) continue;
  54. delta[i]=(a[i]-tp+p)%p;
  55. fail[cnt]=i;
  56. ++cnt;
  57. if(cnt==) {
  58. f[cnt].resize(i);
  59. continue;
  60. }
  61. LL mul=delta[i]*ksm(delta[fail[cnt-]],p-)%p,fmul=(p-mul)%p;
  62. f[cnt].resize(i-fail[cnt-]-);
  63. f[cnt].push_back(mul);
  64. up=f[cnt-].size();
  65. For(j,,up-)
  66. f[cnt].push_back(fmul*f[cnt-][j]%p);
  67. up=f[cnt-].size();
  68. if(f[cnt].size()<f[cnt-].size()) f[cnt].resize(up);
  69. For(j,,up-) f[cnt][j]=(f[cnt][j]+f[cnt-][j])%p;
  70. }
  71. int up=f[cnt].size();
  72. printf("%d\n",up);
  73. For(i,,up-) printf("%lld,",f[cnt][i]);
  74. Formylove;
  75. }

模意义下BM模板

把打出来的表直接放程序里,暴力递推就有80了。

  1. //Achen
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<vector>
  7. #include<cstdio>
  8. #include<queue>
  9. #include<cmath>
  10. #include<set>
  11. #include<map>
  12. #define Formylove return 0
  13. #define For(i,a,b) for(int i=(a);i<=(b);i++)
  14. #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
  15. const int p=;
  16. typedef long long LL;
  17. typedef double db;
  18. using namespace std;
  19. int len[]={,,,,,};
  20. LL f[][]={{},{,,},{,,,,,,},{,,,,,,,,,,,,,,,,,,},{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,},{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,}};
  21. LL a[][]={{},{,,},{,,,,,,},{,,,,,,,,,,,,,,,,,,},{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,},{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,}};
  22. LL b[],n,k;
  23.  
  24. template<typename T>void read(T &x) {
  25. char ch=getchar(); x=; T f=;
  26. while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
  27. if(ch=='-') f=-,ch=getchar();
  28. for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
  29. }
  30.  
  31. #define ANS
  32. int main() {
  33. #ifdef ANS
  34. freopen("shanghai.in","r",stdin);
  35. freopen("shanghai.out","w",stdout);
  36. #endif
  37. read(k); read(n);
  38. For(i,,len[k]) b[i+*k]=a[k][i];
  39. For(i,len[k]+*k+,n) {
  40. For(j,,len[k]) b[i]=(b[i]+f[k][j]*b[i-j]%p)%p;
  41. }
  42. printf("%lld\n",b[n]);
  43. Formylove;
  44. }
  45. /*
  46.  
  47. */

80pt

矩乘优化好像跑不过,得多项式取模优化才行。。。

多项式取模优化k阶常系数线性递推

时间复杂度k^2logn

  1. //Achen
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<vector>
  7. #include<cstdio>
  8. #include<queue>
  9. #include<cmath>
  10. #include<set>
  11. #include<map>
  12. #define Formylove return 0
  13. #define For(i,a,b) for(int i=(a);i<=(b);i++)
  14. #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
  15. const int p=;
  16. typedef long long LL;
  17. typedef double db;
  18. using namespace std;
  19. int len[]={,,,,,};
  20. LL f[][]={{},{,,},{,,,,,,},{,,,,,,,,,,,,,,,,,,},{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,},{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,}};
  21. LL a[][]={{},{,,},{,,,,,,},{,,,,,,,,,,,,,,,,,,},{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,},{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,}};
  22. LL b[],n,k;
  23.  
  24. template<typename T>void read(T &x) {
  25. char ch=getchar(); x=; T f=;
  26. while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
  27. if(ch=='-') f=-,ch=getchar();
  28. for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
  29. }
  30.  
  31. LL rs[],bs[];
  32. void mul(LL a[],LL b[],LL c[]) {
  33. static LL tp[];
  34. int up=(len[k]<<);
  35. For(i,,up) tp[i]=;
  36. For(i,,len[k]-) For(j,,len[k]-)
  37. (tp[i+j]+=a[i]*b[j]%p)%=p;
  38. Rep(i,up,len[k]) For(j,,len[k])
  39. (tp[i-j]+=f[k][j]*tp[i]%p)%=p;
  40. For(i,,up) c[i]=tp[i];
  41. }
  42.  
  43. void ksm(LL b) {
  44. while(b) {
  45. if(b&) mul(rs,bs,rs);
  46. mul(bs,bs,bs);
  47. b>>=;
  48. }
  49. }
  50.  
  51. #define ANS
  52. int main() {
  53. #ifdef ANS
  54. freopen("shanghai.in","r",stdin);
  55. freopen("shanghai.out","w",stdout);
  56. #endif
  57. read(k); read(n);
  58. n-=*k;
  59. For(i,,len[k]) b[i]=a[k][i];
  60. if(n<=len[k]) printf("%lld\n",b[n]);
  61. else {
  62. rs[]=; bs[]=;
  63. ksm(n-);
  64. LL ans=;
  65. For(i,,len[k]-) (ans+=b[i+]*rs[i]%p)%=p;
  66. printf("%lld\n",ans);
  67. }
  68. Formylove;
  69. }

100pt

[NOI2007]生成树计数环形版的更多相关文章

  1. BZOJ1494 [NOI2007]生成树计数

    题意 F.A.Qs Home Discuss ProblemSet Status Ranklist Contest 入门OJ ModifyUser  autoint Logout 捐赠本站 Probl ...

  2. [BZOJ1494][NOI2007]生成树计数 状压dp 并查集

    1494: [NOI2007]生成树计数 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 793  Solved: 451[Submit][Status][ ...

  3. NOI2007 生成树计数

    题目 首先我要吐槽,这题目就是坑,给那么多无用的信息,我还以为要根据提示才能做出来呢! 算法1 暴力,傻傻地跟着提示,纯暴力\(40\)分,高斯消元\(60\)分. 算法2 DP!一个显然的东西是,这 ...

  4. [BZOJ1494]生成树计数

    [BZOJ1494] [NOI2007]生成树计数 Description 最近,小栋在无向连通图的生成树个数计算方面有了惊人的进展,他发现:·n个结点的环的生成树个数为n.·n个结点的完全图的生成树 ...

  5. 【BZOJ1494】【NOI2007】生成树计数(动态规划,矩阵快速幂)

    [BZOJ1494][NOI2007]生成树计数(动态规划,矩阵快速幂) 题面 Description 最近,小栋在无向连通图的生成树个数计算方面有了惊人的进展,他发现: ·n个结点的环的生成树个数为 ...

  6. 【BZOJ1002】【FJOI2007】轮状病毒(生成树计数)

    1002: [FJOI2007]轮状病毒 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 1766  Solved: 946[Submit][Status ...

  7. SPOJ 104 HIGH - Highways 生成树计数

    题目链接:https://vjudge.net/problem/SPOJ-HIGH 解法: 生成树计数 1.构造 基尔霍夫矩阵(又叫拉普拉斯矩阵) n阶矩阵 若u.v之间有边相连 C[u][v]=C[ ...

  8. Luogu P5296 [北京省选集训2019]生成树计数

    Luogu P5296 [北京省选集训2019]生成树计数 题目链接 题目大意:给定每条边的边权.一颗生成树的权值为边权和的\(k\)次方.求出所有生成树的权值和. 我们列出答案的式子: 设\(E\) ...

  9. Loj 2320.「清华集训 2017」生成树计数

    Loj 2320.「清华集训 2017」生成树计数 题目描述 在一个 \(s\) 个点的图中,存在 \(s-n\) 条边,使图中形成了 \(n\) 个连通块,第 \(i\) 个连通块中有 \(a_i\ ...

随机推荐

  1. PDO如何完成事务操作

    起因 无意间翻看极客学院的APP,准备找一些教程看看.看到一篇PDO 安全处理与事务处理,一想对MySQL的事务处理仅仅停留在概念上(知道执行多条语句,其中一个失败了,就会回滚操作).但是把概念变成代 ...

  2. Linux 进程间通信 无名管道(pipe)

    无名管道: 1)只能用于具有亲缘关系的进程之间的通信(无名管道是某一个进程创建的,不像普通文件有路径,在文件系统中是不可见的,其他进程要想打开,只能通过继承的方式去打开) 2)半双工的通信模式,具有固 ...

  3. Peasy.NET学习之并发问题处理

    Peasy.net之并发处理 BusinessServiceBase是ServiceBase的自定义实现,提供了额外的独特功能 首先,创建一个业务服务,该业务服务必须继承BusinessService ...

  4. lib 和 dll 的区别、生成以及使用详解 ~~包含示例代码~~(转)

    原文章地址:https://www.cnblogs.com/TenosDoIt/p/3203137.html#c 首先介绍一下静态库(静态链接库).动态库(动态链接库)的概念,首先两者都是代码共享的方 ...

  5. vue之TodoMVC项目实战

    一.初始化项目 1.下载模板 进入github中https://github.com/tastejs/todomvc-app-template,并且在命令行将其clone下来 git clone ht ...

  6. react css拓展 使用less

    react 之中使用less 其实质只需要看一下resct 使用css的配置项,就能明白个大概了  第一步   还是下载 npm i  less less-loader -save 下载less 和 ...

  7. 对每一个IO操作的返回都要进行判断

    对每一个IO操作的返回都要进行判断 我们业务代码中有很多进行mysql.redis.文件.curl等的io操作,对每一个io操作我们都要对其返回值进行判断,然后做对应的处理,加日志信息或者抛出异常状态 ...

  8. SP2713 GSS4 - Can you answer these queries IV(线段树)

    传送门 解题思路 大概就是一个数很少次数的开方会开到\(1\),而\(1\)开方还是\(1\),所以维护一个和,维护一个开方标记,维护一个区间是否全部为\(1/0\)的标记.然后每次修改时先看是否有全 ...

  9. Annotation详解

    转自:http://www.doc88.com/p-995532241886.html 首先我们定义一个简单的注解 package com.qjy.annotation; import java.la ...

  10. flutter 超出俩行点点点

    Text( '${listItem["title"]}', overflow: TextOverflow.ellipsis, maxLines: 2, style: TextSty ...