• 牛客网暑期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 }
  • 相关阅读:
    安装docker
    docker安装完成后测试feisky/nginx:latest 出现问题(Unable to find image 'feisky/nginx:latest' locally)
    负载均衡详细介绍
    docker(一)
    AppCrawer使用(2)
    AppCrawer使用入门(转自https://www.cnblogs.com/alwayswyy/p/7576964.html,感谢原作者)
    获取包名和活动名
    (十八)Collection集合
    (十七)面向对象之内部类
    (十五)final关键字
  • 原文地址:https://www.cnblogs.com/stranger-/p/9548762.html
Copyright © 2020-2023  润新知