[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\ ...
随机推荐
- 笔记:TCP/IP基础知识
TCP/IP是指利用IP进行通信时必须用到的协议群的统称. 互联网层(网络层) IP IP是跨越网络传送数据包,使整个网络都能收到数据的协议.IP地址在发送数据的时候作为主机的标识. ICMP 用来诊 ...
- nginx打包成rpm
[root@localhost ~ ]#yum -y install lrzsz pcre pcre-devel zlib zlib-devel vim nrt-tools psmisc gcc gc ...
- svn 一、 安装及汉化
svn 是日常开发过程中常用的版本控制工具 第一步 安装 进入官网 https://tortoisesvn.net/ 点击downloads 进入之后选中 需要的版本,及位数 这里推荐安装最新版的 因 ...
- ASCII 对应表
{ Bin (二进制) Oct (八进制) Dec (十进制) Hex (十六进制) 缩写/字符 解释 0000 0000 00 0 0x00 NUL(null) 空字符 0000 0001 01 1 ...
- 最佳实践:阿里云VPC、ECS支持IPv6啦!
12月6日,阿里云宣布为企业提供全栈IPv6解决方案. 阿里云专有网络VPC.云服务器ECS,作为阿里云的核心产品,也于2018年11月底上线双栈VPC.双栈ECS,目前正在对外公测中. 那么如何在阿 ...
- 依赖背包变形(经典)——poj1155
这个题用优化后的依赖背包做难以实现,所以用常规的泛化物品的和来做即可 每个节点的容量定义为这个节点下的叶子结点个数,dp[u][j]用来表示节点u下选取j个物品的最大收益,最后从m-0查询dp[1][ ...
- 移动端多选插件-jquery
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- hdu多校第六场1008 (hdu6641)TDL 暴力
题意: 设f(n,m)为比n大的第m个和n互质的数,给定一个k=(f(n,m)-n)xor n和m,求最小的n 题解: 对于给定的m而言,一个k周围合法的n分布的很密,因此在k的邻域暴力搜索即可. # ...
- topjui.common.js
function getTabWindow() { var curTabWin = null; if (topJUI.config.aloneUse) { curTabWin = window; } ...
- solr 如何实现精确查询
第一条和第三条不应该出现的. 解决办法