[NOI2007]生成树计数环形版
NOI2007这道题人类进化更完全之后出现了新的做法
毕姥爷题解:
于是毕姥爷出了一道环形版的这题(test0814),让我们写这个做法
环形的情况下,k=5的时候是162阶递推。
求这个递推可以用BM算法
- //Achen
- #include<algorithm>
- #include<iostream>
- #include<cstring>
- #include<cstdlib>
- #include<vector>
- #include<cstdio>
- #include<queue>
- #include<cmath>
- #include<set>
- #include<map>
- #define Formylove return 0
- #define For(i,a,b) for(int i=(a);i<=(b);i++)
- #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
- const int p=;
- typedef long long LL;
- typedef double db;
- using namespace std;
- int k;
- template<typename T>void read(T &x) {
- char ch=getchar(); x=; T f=;
- while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
- if(ch=='-') f=-,ch=getchar();
- for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
- }
- LL a[][];
- LL solve(int n) {
- LL rs=,f=;
- For(i,,n) For(j,,n) a[i][j]=(a[i][j]+p)%p;
- For(i,,n) {
- For(j,i+,n) {
- LL A=a[i][i],B=a[j][i],t;
- while(B) {
- t=A/B;
- For(k,i,n) a[i][k]=(a[i][k]-t*a[j][k]%p+p)%p;
- For(k,i,n) swap(a[i][k],a[j][k]);
- A%=B; swap(A,B); f=-f;
- }
- }
- rs=rs*a[i][i]%p;
- }
- if(f==-) rs=p-rs;
- return rs;
- }
- #define ANS
- int main() {
- #ifdef ANS
- //freopen("shanghai.in","r",stdin);
- freopen("biao.out","w",stdout);
- #endif
- read(k);
- //printf("%d\n",500-2*k);
- int tot=;
- For(n,*k+,) {
- tot++;
- For(i,,n) For(j,i+,n) if(min(abs(i-j),n-abs(i-j))<=k) {
- a[i][i]++;
- a[j][j]++;
- a[i][j]--;
- a[j][i]--;
- }
- LL rs=solve(n-);
- printf("%lld,",rs);
- For(i,,n) For(j,,n) a[i][j]=;
- if(tot==) break;
- }
- Formylove;
- }
暴力程序(矩阵树定理)
对于每个k用上面这个暴力打表,再用下面这个模板得出递推(ps,BM算法n越大越精确,当k=5,n只取到200时会得出90多阶的递推而不是162阶)
- //Achen
- #include<algorithm>
- #include<iostream>
- #include<cstring>
- #include<cstdlib>
- #include<vector>
- #include<cstdio>
- #include<queue>
- #include<cmath>
- #include<set>
- #include<map>
- #define Formylove return 0
- #define For(i,a,b) for(int i=(a);i<=(b);i++)
- #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
- const int N=,p=;
- typedef long long LL;
- typedef double db;
- using namespace std;
- int n,cnt,fail[N];
- vector<LL>f[N];
- LL a[N],delta[N];
- template<typename T>void read(T &x) {
- char ch=getchar(); x=; T f=;
- while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
- if(ch=='-') f=-,ch=getchar();
- for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
- }
- LL ksm(LL a,LL b) {
- LL rs=,bs=a%p;
- while(b) {
- if(b&) rs=rs*bs%p;
- bs=bs*bs%p;
- b>>=;
- }
- return rs;
- }
- #define ANS
- int main() {
- #ifdef ANS
- freopen("biao.out","r",stdin);
- freopen("k4.out","w",stdout);
- #endif
- read(n);
- For(i,,n) read(a[i]);
- For(i,,n) {
- LL tp=;
- int up=f[cnt].size();
- For(j,,up-)
- tp=(tp+f[cnt][j]*a[i-j-]%p)%p;
- if(tp==a[i]) continue;
- delta[i]=(a[i]-tp+p)%p;
- fail[cnt]=i;
- ++cnt;
- if(cnt==) {
- f[cnt].resize(i);
- continue;
- }
- LL mul=delta[i]*ksm(delta[fail[cnt-]],p-)%p,fmul=(p-mul)%p;
- f[cnt].resize(i-fail[cnt-]-);
- f[cnt].push_back(mul);
- up=f[cnt-].size();
- For(j,,up-)
- f[cnt].push_back(fmul*f[cnt-][j]%p);
- up=f[cnt-].size();
- if(f[cnt].size()<f[cnt-].size()) f[cnt].resize(up);
- For(j,,up-) f[cnt][j]=(f[cnt][j]+f[cnt-][j])%p;
- }
- int up=f[cnt].size();
- printf("%d\n",up);
- For(i,,up-) printf("%lld,",f[cnt][i]);
- Formylove;
- }
模意义下BM模板
把打出来的表直接放程序里,暴力递推就有80了。
- //Achen
- #include<algorithm>
- #include<iostream>
- #include<cstring>
- #include<cstdlib>
- #include<vector>
- #include<cstdio>
- #include<queue>
- #include<cmath>
- #include<set>
- #include<map>
- #define Formylove return 0
- #define For(i,a,b) for(int i=(a);i<=(b);i++)
- #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
- const int p=;
- typedef long long LL;
- typedef double db;
- using namespace std;
- int len[]={,,,,,};
- LL f[][]={{},{,,},{,,,,,,},{,,,,,,,,,,,,,,,,,,},{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,},{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,}};
- LL a[][]={{},{,,},{,,,,,,},{,,,,,,,,,,,,,,,,,,},{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,},{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,}};
- LL b[],n,k;
- template<typename T>void read(T &x) {
- char ch=getchar(); x=; T f=;
- while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
- if(ch=='-') f=-,ch=getchar();
- for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
- }
- #define ANS
- int main() {
- #ifdef ANS
- freopen("shanghai.in","r",stdin);
- freopen("shanghai.out","w",stdout);
- #endif
- read(k); read(n);
- For(i,,len[k]) b[i+*k]=a[k][i];
- For(i,len[k]+*k+,n) {
- For(j,,len[k]) b[i]=(b[i]+f[k][j]*b[i-j]%p)%p;
- }
- printf("%lld\n",b[n]);
- Formylove;
- }
- /*
- */
80pt
矩乘优化好像跑不过,得多项式取模优化才行。。。
时间复杂度k^2logn
- //Achen
- #include<algorithm>
- #include<iostream>
- #include<cstring>
- #include<cstdlib>
- #include<vector>
- #include<cstdio>
- #include<queue>
- #include<cmath>
- #include<set>
- #include<map>
- #define Formylove return 0
- #define For(i,a,b) for(int i=(a);i<=(b);i++)
- #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
- const int p=;
- typedef long long LL;
- typedef double db;
- using namespace std;
- int len[]={,,,,,};
- LL f[][]={{},{,,},{,,,,,,},{,,,,,,,,,,,,,,,,,,},{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,},{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,}};
- LL a[][]={{},{,,},{,,,,,,},{,,,,,,,,,,,,,,,,,,},{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,},{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,}};
- LL b[],n,k;
- template<typename T>void read(T &x) {
- char ch=getchar(); x=; T f=;
- while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
- if(ch=='-') f=-,ch=getchar();
- for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
- }
- LL rs[],bs[];
- void mul(LL a[],LL b[],LL c[]) {
- static LL tp[];
- int up=(len[k]<<);
- For(i,,up) tp[i]=;
- For(i,,len[k]-) For(j,,len[k]-)
- (tp[i+j]+=a[i]*b[j]%p)%=p;
- Rep(i,up,len[k]) For(j,,len[k])
- (tp[i-j]+=f[k][j]*tp[i]%p)%=p;
- For(i,,up) c[i]=tp[i];
- }
- void ksm(LL b) {
- while(b) {
- if(b&) mul(rs,bs,rs);
- mul(bs,bs,bs);
- b>>=;
- }
- }
- #define ANS
- int main() {
- #ifdef ANS
- freopen("shanghai.in","r",stdin);
- freopen("shanghai.out","w",stdout);
- #endif
- read(k); read(n);
- n-=*k;
- For(i,,len[k]) b[i]=a[k][i];
- if(n<=len[k]) printf("%lld\n",b[n]);
- else {
- rs[]=; bs[]=;
- ksm(n-);
- LL ans=;
- For(i,,len[k]-) (ans+=b[i+]*rs[i]%p)%=p;
- printf("%lld\n",ans);
- }
- Formylove;
- }
100pt
[NOI2007]生成树计数环形版的更多相关文章
- BZOJ1494 [NOI2007]生成树计数
题意 F.A.Qs Home Discuss ProblemSet Status Ranklist Contest 入门OJ ModifyUser autoint Logout 捐赠本站 Probl ...
- [BZOJ1494][NOI2007]生成树计数 状压dp 并查集
1494: [NOI2007]生成树计数 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 793 Solved: 451[Submit][Status][ ...
- NOI2007 生成树计数
题目 首先我要吐槽,这题目就是坑,给那么多无用的信息,我还以为要根据提示才能做出来呢! 算法1 暴力,傻傻地跟着提示,纯暴力\(40\)分,高斯消元\(60\)分. 算法2 DP!一个显然的东西是,这 ...
- [BZOJ1494]生成树计数
[BZOJ1494] [NOI2007]生成树计数 Description 最近,小栋在无向连通图的生成树个数计算方面有了惊人的进展,他发现:·n个结点的环的生成树个数为n.·n个结点的完全图的生成树 ...
- 【BZOJ1494】【NOI2007】生成树计数(动态规划,矩阵快速幂)
[BZOJ1494][NOI2007]生成树计数(动态规划,矩阵快速幂) 题面 Description 最近,小栋在无向连通图的生成树个数计算方面有了惊人的进展,他发现: ·n个结点的环的生成树个数为 ...
- 【BZOJ1002】【FJOI2007】轮状病毒(生成树计数)
1002: [FJOI2007]轮状病毒 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 1766 Solved: 946[Submit][Status ...
- SPOJ 104 HIGH - Highways 生成树计数
题目链接:https://vjudge.net/problem/SPOJ-HIGH 解法: 生成树计数 1.构造 基尔霍夫矩阵(又叫拉普拉斯矩阵) n阶矩阵 若u.v之间有边相连 C[u][v]=C[ ...
- Luogu P5296 [北京省选集训2019]生成树计数
Luogu P5296 [北京省选集训2019]生成树计数 题目链接 题目大意:给定每条边的边权.一颗生成树的权值为边权和的\(k\)次方.求出所有生成树的权值和. 我们列出答案的式子: 设\(E\) ...
- Loj 2320.「清华集训 2017」生成树计数
Loj 2320.「清华集训 2017」生成树计数 题目描述 在一个 \(s\) 个点的图中,存在 \(s-n\) 条边,使图中形成了 \(n\) 个连通块,第 \(i\) 个连通块中有 \(a_i\ ...
随机推荐
- PDO如何完成事务操作
起因 无意间翻看极客学院的APP,准备找一些教程看看.看到一篇PDO 安全处理与事务处理,一想对MySQL的事务处理仅仅停留在概念上(知道执行多条语句,其中一个失败了,就会回滚操作).但是把概念变成代 ...
- Linux 进程间通信 无名管道(pipe)
无名管道: 1)只能用于具有亲缘关系的进程之间的通信(无名管道是某一个进程创建的,不像普通文件有路径,在文件系统中是不可见的,其他进程要想打开,只能通过继承的方式去打开) 2)半双工的通信模式,具有固 ...
- Peasy.NET学习之并发问题处理
Peasy.net之并发处理 BusinessServiceBase是ServiceBase的自定义实现,提供了额外的独特功能 首先,创建一个业务服务,该业务服务必须继承BusinessService ...
- lib 和 dll 的区别、生成以及使用详解 ~~包含示例代码~~(转)
原文章地址:https://www.cnblogs.com/TenosDoIt/p/3203137.html#c 首先介绍一下静态库(静态链接库).动态库(动态链接库)的概念,首先两者都是代码共享的方 ...
- vue之TodoMVC项目实战
一.初始化项目 1.下载模板 进入github中https://github.com/tastejs/todomvc-app-template,并且在命令行将其clone下来 git clone ht ...
- react css拓展 使用less
react 之中使用less 其实质只需要看一下resct 使用css的配置项,就能明白个大概了 第一步 还是下载 npm i less less-loader -save 下载less 和 ...
- 对每一个IO操作的返回都要进行判断
对每一个IO操作的返回都要进行判断 我们业务代码中有很多进行mysql.redis.文件.curl等的io操作,对每一个io操作我们都要对其返回值进行判断,然后做对应的处理,加日志信息或者抛出异常状态 ...
- SP2713 GSS4 - Can you answer these queries IV(线段树)
传送门 解题思路 大概就是一个数很少次数的开方会开到\(1\),而\(1\)开方还是\(1\),所以维护一个和,维护一个开方标记,维护一个区间是否全部为\(1/0\)的标记.然后每次修改时先看是否有全 ...
- Annotation详解
转自:http://www.doc88.com/p-995532241886.html 首先我们定义一个简单的注解 package com.qjy.annotation; import java.la ...
- flutter 超出俩行点点点
Text( '${listItem["title"]}', overflow: TextOverflow.ellipsis, maxLines: 2, style: TextSty ...