zoukankan      html  css  js  c++  java
  • 牛客网暑期ACM多校训练营(第九场)D

    链接: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.

    示例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   感觉应该是有什么规律,打个表怀疑可能是线性递推,试着下一下就是了。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 #define rep(i,a,n) for (int i=a;i<n;i++)
      4 #define per(i,a,n) for (int i=n-1;i>=a;i--)
      5 #define pb push_back
      6 #define mp make_pair
      7 #define all(x) (x).begin(),(x).end()
      8 #define fi first
      9 #define se second
     10 #define SZ(x) ((int)(x).size())
     11 typedef vector<int> VI;
     12 typedef long long ll;
     13 typedef pair<int,int> PII;
     14 const ll mod=1000000007;
     15 ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
     16 // head
     17  
     18 namespace linear_seq {
     19     const int N=10010;
     20     ll res[N],base[N],_c[N],_md[N];
     21     vector<int> Md;
     22     void mul(ll *a,ll *b,int k) {
     23         rep(i,0,k+k) _c[i]=0;
     24         rep(i,0,k) if (a[i]) rep(j,0,k) _c[i+j]=(_c[i+j]+a[i]*b[j])%mod;
     25         for (int i=k+k-1;i>=k;i--) if (_c[i])
     26             rep(j,0,SZ(Md)) _c[i-k+Md[j]]=(_c[i-k+Md[j]]-_c[i]*_md[Md[j]])%mod;
     27         rep(i,0,k) a[i]=_c[i];
     28     }
     29     int solve(ll n,VI a,VI b) { // a 系数 b 初值 b[n+1]=a[0]*b[n]+...
     30 //        printf("SIZE %d
    ",SZ(b));
     31         ll ans=0,pnt=0;
     32         int k=SZ(a);
     33         assert(SZ(a)==SZ(b));
     34         rep(i,0,k) _md[k-1-i]=-a[i];_md[k]=1;
     35         Md.clear();
     36         rep(i,0,k) if (_md[i]!=0) Md.push_back(i);
     37         rep(i,0,k) res[i]=base[i]=0;
     38         res[0]=1;
     39         while ((1ll<<pnt)<=n) pnt++;
     40         for (int p=pnt;p>=0;p--) {
     41             mul(res,res,k);
     42             if ((n>>p)&1) {
     43                 for (int i=k-1;i>=0;i--) res[i+1]=res[i];res[0]=0;
     44                 rep(j,0,SZ(Md)) res[Md[j]]=(res[Md[j]]-res[k]*_md[Md[j]])%mod;
     45             }
     46         }
     47         rep(i,0,k) ans=(ans+res[i]*b[i])%mod;
     48         if (ans<0) ans+=mod;
     49         return ans;
     50     }
     51     VI BM(VI s) {
     52         VI C(1,1),B(1,1);
     53         int L=0,m=1,b=1;
     54         rep(n,0,SZ(s)) {
     55             ll d=0;
     56             rep(i,0,L+1) d=(d+(ll)C[i]*s[n-i])%mod;
     57             if (d==0) ++m;
     58             else if (2*L<=n) {
     59                 VI T=C;
     60                 ll c=mod-d*powmod(b,mod-2)%mod;
     61                 while (SZ(C)<SZ(B)+m) C.pb(0);
     62                 rep(i,0,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;
     63                 L=n+1-L; B=T; b=d; m=1;
     64             } else {
     65                 ll c=mod-d*powmod(b,mod-2)%mod;
     66                 while (SZ(C)<SZ(B)+m) C.pb(0);
     67                 rep(i,0,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;
     68                 ++m;
     69             }
     70         }
     71         return C;
     72     }
     73     int gao(VI a,ll n) {
     74         VI c=BM(a);
     75         c.erase(c.begin());
     76         rep(i,0,SZ(c)) c[i]=(mod-c[i])%mod;
     77         return solve(n,c,VI(a.begin(),a.begin()+SZ(c)));
     78     }
     79 };
     80 int a[2020][2020];
     81 ll det(int n) {
     82     ll ans = 1;
     83     for (int i = 0; i < n; i++) {
     84         for (int j = i + 1; j < n; j++) {
     85             while (a[j][i] != 0) {
     86                 int u = a[i][i] / a[j][i];
     87                 for (int k = 0; k < n; k++) {
     88                     int t = (a[i][k] - (ll)a[j][k] * u % mod + mod) % mod;
     89                     a[i][k] = a[j][k];
     90                     a[j][k] = t;
     91                 }
     92                 ans = -ans;
     93             }
     94         }
     95         ans = ans * a[i][i] % mod;
     96     }
     97     if (ans < 0) {
     98         ans += mod;
     99     }
    100     return ans;
    101 }
    102 ll work(int k, int n) {     //构造矩阵 计算点数为n的欧拉回路个数
    103     memset(a, 0, sizeof a);
    104     for (int i = 0; i < n; i++) {
    105         a[i][i] = k;
    106         for (int j = 1; j <= k; j++) {
    107             a[i][(i + j) % n] = -1;
    108         }
    109     }
    110     ll t = 1;
    111     for (int i = 1; i < k; i++) {   //度数-1的阶乘
    112         t = t * i % mod;
    113     }
    114     return (ll)det(n - 1) * powmod(t, n) % mod; // 每个点的度数都一样 所以直接快速幂。
    115 }
    116 int main() {
    117     int k;
    118     ll n;
    119     cin >> k >> n;
    120     vector<int> a;
    121     for (int i = 2 * k + 1; i <= (1 << k)+ 2 * k + 1; i++) { //为什么是1<<k这么多项 也也不知道 题解说的。。。 正常写就在不超时的情况下尽量写大点呗
    122             a.push_back(work(k, i));
    123     }
    124     cout << linear_seq::gao(a, n - (2 * k + 1)) << endl;
    125     return 0;
    126 }
  • 相关阅读:
    css浮动 blog_zss小帅
    块级元素和行内元素 blog_zss小帅
    css清除常用标签默认样式表 blog_zss小帅
    css三种基本选着器 blog_zss小帅
    Flex 弹性盒基本语法 blog_zss小帅
    利用this属性实现点击按钮变色.选中效果 blog_zss小帅
    Form中Block的重新查询
    Form中Block的Data source基于View的开发
    客制的出货功能非常慢
    form builder画布跟着鼠标滚轮上下跳动
  • 原文地址:https://www.cnblogs.com/stranger-/p/9548762.html
Copyright © 2011-2022 走看看