链接:https://www.nowcoder.com/acm/contest/147/D
来源:牛客网

Niuniu likes traveling. Now he will travel on a special graph.

Given k and n, The directed graph contains n vertices, which are numbered from 0 to n - 1.

For the vertex i, and for 1 <= j <= k, there is a directed edge from vertex i to vertex ((i + j) % n). 
We want to know the number of (directed) cycles, that pass each directed edge exactly once.
As the answer might be very large, you only need to output the answer mod 1000000007.

输入描述:

The first and only line contains two integers, which are k and n.
 
1 <= k <= 7
2k+1 <= n <= 109

输出描述:

The first and only line contains the answer.

输入例子:
2 5
输出例子:
11

-->

示例1

输入

2 5

输出

11

说明

The answer is not 22.
0 -> 1- > 2 -> 3 -> 4 -> 0 -> 2 -> 4 -> 1 -> 3 -> 0. 0 -> 2 -> 4 -> 1 -> 3 -> 0 -> 1 -> 2 -> 3 -> 4 -> 0. The two cycles are the same. They all passed the 10 edges. Only the start edges are different, and we think they are the same.

输入

3 8

输出

278528

解析   按照以上方式建立有向图 求欧拉回路的个数 。首先我们知道BEST定理 用矩阵求解欧拉回路的个数。但是题目给的点数太多,不能直接暴力

   每个点的出度和入度都为K   感觉应该是有什么规律,打个表怀疑可能是线性递推,试着下一下就是了。

 #include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const ll mod=;
ll powmod(ll a,ll b) {ll res=;a%=mod; assert(b>=); for(;b;b>>=){if(b&)res=res*a%mod;a=a*a%mod;}return res;}
// head namespace linear_seq {
const int N=;
ll res[N],base[N],_c[N],_md[N];
vector<int> Md;
void mul(ll *a,ll *b,int k) {
rep(i,,k+k) _c[i]=;
rep(i,,k) if (a[i]) rep(j,,k) _c[i+j]=(_c[i+j]+a[i]*b[j])%mod;
for (int i=k+k-;i>=k;i--) if (_c[i])
rep(j,,SZ(Md)) _c[i-k+Md[j]]=(_c[i-k+Md[j]]-_c[i]*_md[Md[j]])%mod;
rep(i,,k) a[i]=_c[i];
}
int solve(ll n,VI a,VI b) { // a 系数 b 初值 b[n+1]=a[0]*b[n]+...
// printf("SIZE %d\n",SZ(b));
ll ans=,pnt=;
int k=SZ(a);
assert(SZ(a)==SZ(b));
rep(i,,k) _md[k--i]=-a[i];_md[k]=;
Md.clear();
rep(i,,k) if (_md[i]!=) Md.push_back(i);
rep(i,,k) res[i]=base[i]=;
res[]=;
while ((1ll<<pnt)<=n) pnt++;
for (int p=pnt;p>=;p--) {
mul(res,res,k);
if ((n>>p)&) {
for (int i=k-;i>=;i--) res[i+]=res[i];res[]=;
rep(j,,SZ(Md)) res[Md[j]]=(res[Md[j]]-res[k]*_md[Md[j]])%mod;
}
}
rep(i,,k) ans=(ans+res[i]*b[i])%mod;
if (ans<) ans+=mod;
return ans;
}
VI BM(VI s) {
VI C(,),B(,);
int L=,m=,b=;
rep(n,,SZ(s)) {
ll d=;
rep(i,,L+) d=(d+(ll)C[i]*s[n-i])%mod;
if (d==) ++m;
else if (*L<=n) {
VI T=C;
ll c=mod-d*powmod(b,mod-)%mod;
while (SZ(C)<SZ(B)+m) C.pb();
rep(i,,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;
L=n+-L; B=T; b=d; m=;
} else {
ll c=mod-d*powmod(b,mod-)%mod;
while (SZ(C)<SZ(B)+m) C.pb();
rep(i,,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;
++m;
}
}
return C;
}
int gao(VI a,ll n) {
VI c=BM(a);
c.erase(c.begin());
rep(i,,SZ(c)) c[i]=(mod-c[i])%mod;
return solve(n,c,VI(a.begin(),a.begin()+SZ(c)));
}
};
int a[][];
ll det(int n) {
ll ans = ;
for (int i = ; i < n; i++) {
for (int j = i + ; j < n; j++) {
while (a[j][i] != ) {
int u = a[i][i] / a[j][i];
for (int k = ; k < n; k++) {
int t = (a[i][k] - (ll)a[j][k] * u % mod + mod) % mod;
a[i][k] = a[j][k];
a[j][k] = t;
}
ans = -ans;
}
}
ans = ans * a[i][i] % mod;
}
if (ans < ) {
ans += mod;
}
return ans;
}
ll work(int k, int n) { //构造矩阵 计算点数为n的欧拉回路个数
memset(a, , sizeof a);
for (int i = ; i < n; i++) {
a[i][i] = k;
for (int j = ; j <= k; j++) {
a[i][(i + j) % n] = -;
}
}
ll t = ;
for (int i = ; i < k; i++) { //度数-1的阶乘
t = t * i % mod;
}
return (ll)det(n - ) * powmod(t, n) % mod; // 每个点的度数都一样 所以直接快速幂。
}
int main() {
int k;
ll n;
cin >> k >> n;
vector<int> a;
for (int i = * k + ; i <= ( << k)+ * k + ; i++) { //为什么是1<<k这么多项 也也不知道 题解说的。。。 正常写就在不超时的情况下尽量写大点呗
a.push_back(work(k, i));
}
cout << linear_seq::gao(a, n - ( * k + )) << endl;
return ;
}

牛客网暑期ACM多校训练营(第九场)D的更多相关文章

  1. 牛客网暑期ACM多校训练营 第九场

    HPrefix Sum study from : https://blog.csdn.net/mitsuha_/article/details/81774727 k较小.分离x和k. 另外的可能:求a ...

  2. 牛客网暑期ACM多校训练营(第四场):A Ternary String(欧拉降幂)

    链接:牛客网暑期ACM多校训练营(第四场):A Ternary String 题意:给出一段数列 s,只包含 0.1.2 三种数.每秒在每个 2 后面会插入一个 1 ,每个 1 后面会插入一个 0,之 ...

  3. 牛客网暑期ACM多校训练营(第五场):F - take

    链接:牛客网暑期ACM多校训练营(第五场):F - take 题意: Kanade有n个盒子,第i个盒子有p [i]概率有一个d [i]大小的钻石. 起初,Kanade有一颗0号钻石.她将从第1到第n ...

  4. 牛客网 暑期ACM多校训练营(第二场)A.run-动态规划 or 递推?

    牛客网暑期ACM多校训练营(第二场) 水博客. A.run 题意就是一个人一秒可以走1步或者跑K步,不能连续跑2秒,他从0开始移动,移动到[L,R]的某一点就可以结束.问一共有多少种移动的方式. 个人 ...

  5. 牛客网 暑期ACM多校训练营(第一场)A.Monotonic Matrix-矩阵转化为格子路径的非降路径计数,Lindström-Gessel-Viennot引理-组合数学

    牛客网暑期ACM多校训练营(第一场) A.Monotonic Matrix 这个题就是给你一个n*m的矩阵,往里面填{0,1,2}这三种数,要求是Ai,j⩽Ai+1,j,Ai,j⩽Ai,j+1 ,问你 ...

  6. 牛客网暑期ACM多校训练营(第三场)H Diff-prime Pairs (贡献)

    牛客网暑期ACM多校训练营(第三场)H Diff-prime Pairs (贡献) 链接:https://ac.nowcoder.com/acm/contest/141/H来源:牛客网 Eddy ha ...

  7. 2018牛客网暑期ACM多校训练营(第二场)I- car ( 思维)

    2018牛客网暑期ACM多校训练营(第二场)I- car 链接:https://ac.nowcoder.com/acm/contest/140/I来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 ...

  8. 牛客网暑期ACM多校训练营(第七场)Bit Compression

    链接:https://www.nowcoder.com/acm/contest/145/C 来源:牛客网 题目描述 A binary string s of length N = 2n is give ...

  9. 牛客网暑期ACM多校训练营(第一场) - J Different Integers(线段数组or莫队)

    链接:https://www.nowcoder.com/acm/contest/139/J来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 524288K,其他语言1048 ...

  10. 牛客网暑期ACM多校训练营(第九场) A题 FWT

    链接:https://www.nowcoder.com/acm/contest/147/A来源:牛客网 Niuniu has recently learned how to use Gaussian ...

随机推荐

  1. webuploader上传工具

    http://fex.baidu.com/webuploader/getting-started.html#显示用户选择 Html部分 首先准备dom结构,包含存放文件信息的容器.选择按钮和上传按钮三 ...

  2. Redis学习笔记(三)列表进阶

    RPOPLPUSH source destination(弹出source列表最右端的元素,并推入destination的最左端,同时返回这个元素) BRPOPLPUSH source destina ...

  3. Oracle EXPDP and IMPDP

    一.特点 • 可通过 DBMS_DATAPUMP 调用 • 可提供以下工具: – expdp – impdp – 基于 Web 的界面 • 提供四种数据移动方法: – 数据文件复制 – 直接路径 – ...

  4. dzzoffice网盘应用有着最强大的团队、企业私有网盘功能,并且全开源无功能限制。

    企业,团队多人使用dzzoffice的网盘应用,灵活并且功能强大. 支持个人网盘,机构部门,群组,并可根据使用情况开启关闭.例如可只开启群组功能.   可通过后缀,标签自定义类型进行快捷筛选   全面 ...

  5. END - 提交当前的事务

    SYNOPSIS END [ WORK | TRANSACTION ] DESCRIPTION 描述 END END 提交当前事务. 所有当前事务做的修改都可被其它事务看到并且保证在发生崩溃的情况下的 ...

  6. sklearn之SVC

    sklearn.svm.SVC(C=1.0, kernel='rbf', degree=3, gamma='auto', coef0=0.0, shrinking=True, probability= ...

  7. centOS7安装 mysql-community-release-el7-5.noarch.rpm 包

    一.rpm包 1.wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm(下载rpm) 2.rpm -ivh mysql ...

  8. js&jquery页面加载完执行

    js <script type=”text/javascript”> window.onload=function (){ var userName=”xiaoming”; alert(u ...

  9. JS常用字符串处理方法应用总结

    这篇文章主要总结了JS常用字符串的处理方法,需要的朋友可以参考下   1.indexOf()方法,从前往后查找字符串位置,大小写敏感,从0开始计数.同理,lastIndexOf() 方法从后往前,两个 ...

  10. [LOJ] 分块九题 7

    区间加法,区间乘法,单点查询. 洛谷线段树2 屡清加法乘法的关系,定义答案为 a*mut+add 对于整块: 新的乘w,mut和add都要乘w 新的加w,add加w //Stay foolish,st ...