[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\ ...
随机推荐
- [翻译]windows下 连接到 bitnami的phpmyadmin
bitnami 因为安全考虑,只能 localhost 访问 phpmyadmin 为了能通过SSH 隧道访问 phpMyAdmin,你需要一个ssh 客户端.参考文章介绍使用中选择使用 PuTTY, ...
- git删除远程服务的文件夹
首先查看当前分支:git branch -a 删除缓存的idea:git rm --cached -r .idea 提交gitiginore文件,将.idea从源代码仓库中删除(-m 表示注解): ...
- 前端mockjs模拟图片验证码
ps:mockjs在进行相同的双数次请求的时候,会出现请求404的状况,希望有大佬帮解决下 首先创建dom <img id='bbn' src="" alt="图图 ...
- Kotlin Doc
{ https://www.runoob.com/kotlin/kotlin-eclipse-setup.html }
- JAVA 调用c++ 扩展 批评那些垃圾,
//本人喜欢用命令行的方式,这样好理解原理 { 1 生成的要是X64 并且是release版本 不要预编译头的dll项目,就是创建的时是一个空dll项目 2 java 调用时要import com.m ...
- thinkphp 数据分页
通常在数据查询后都会对数据集进行分页操作,ThinkPHP也提供了分页类来对数据分页提供支持. 下面是数据分页的两种示例. 第一种:利用Page类和limit方法 $User = M('User'); ...
- 暑假集训test-8-31(pm)
以为可以AK,结果t3没有调出来,然后被林巨踩了. everyday被踩,很开心. 林巨真的好巨啊,这么多天已经总计虐我75分了. 1.玩具装箱 第一眼还以为是那道斜率优化dp,结果是个签到水题. / ...
- NX二次开发-UFUN圆弧矩阵标记、起始角和结束角(弧度测量)、圆弧中心坐标和圆弧半径UF_CURVE_ask_arc_data(边可以用)
1 NX11+VS2013 2 3 #include <uf.h> 4 #include <uf_ui.h> 5 #include <uf_modl.h> 6 #i ...
- (转)OC学习笔记 @property的属性 strong 和 weak 理解
在ObjectiveC里,用@property访问所有的实例变量.@property有一对属性:strong 和 weak.官方文档里的解释晦涩难懂:Stack Overflow里的用户RDC (ht ...
- Qt无边框窗口的移动、拉伸边框、鼠标滚轮缩放大小
主要是处理窗口上鼠标的几个事件,具体代码请看下面的截图, 完整代码的下载链接在此:http://download.csdn.net/detail/beyond0824/9657110, 本示例代码中, ...