Dang_Quan_10_Tin

DREAM

Sep 17th, 2020
369
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.25 KB | None | 0 0
  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. #include <cstring>
  5. #include <map>
  6. #include <unordered_map>
  7. #define task "DREAM"
  8. #define int int_fast32_t
  9. using namespace std;
  10. using ll = int_fast64_t;
  11. using ld = long double;
  12.  
  13. const int N = 1e2 + 2;
  14. const ll mod = 1e9 + 7;
  15. int sz;
  16. struct Matrix{
  17.     ll a[N][N];
  18.     Matrix() {fill_n(&a[0][0], N * N, 0);}
  19.     Matrix operator * (const Matrix &m) {
  20.         Matrix ans;
  21.         for(int i = 1; i < sz; ++i)
  22.             for(int j = 1; j < sz; ++j)
  23.                 for(int t = 1; t < sz; ++t){
  24.                     auto &v = ans.a[i][t];
  25.                     v += a[i][j] * m.a[j][t];
  26.                     if(v > mod || v < -mod)
  27.                         v %= mod;
  28.                 }
  29.         return ans;
  30.     }
  31. };
  32.  
  33. Matrix Pow(Matrix &a, ll b){
  34.     Matrix tmp;
  35.     for(int i = 1; i < sz; ++i)
  36.         tmp.a[i][i] = 1;
  37.     for(; b > 0; b >>= 1){
  38.         if(b & 1) tmp = tmp * a;
  39.         a = a * a;
  40.     }
  41.     return tmp;
  42. }
  43.  
  44. int n;
  45. ll k, s[N];
  46. int dp[N];
  47.  
  48. template<class T>
  49. void read(T &x){
  50.     register int c;
  51.     x = 0;
  52.     while((c = getchar()) && c < '0' || c > '9');
  53.     for(; c >= '0' && c <= '9'; c = getchar())
  54.         x = x * 10 + c - '0';
  55. }
  56.  
  57. void Read(){
  58.     read(n); read(k);
  59.     for(int i = 1; i <= n; ++i){
  60.         int d; read(d);
  61.         ++s[d];
  62.         sz = max(sz, d + 2);
  63.     }
  64. }
  65.  
  66. void Forces(){
  67.     dp[0] = 1;
  68.     for(ll i = 1; i <= k; ++i){
  69.         for(int j = 1; j < sz; ++j)
  70.             if(i >= j){
  71.                 dp[i] = (dp[i] + s[j] * dp[i - j] % mod ) % mod;
  72.                 if(i - j > 0)
  73.                     dp[i] = (dp[i] - s[j] * dp[i - j - 1]) % mod;
  74.             }
  75.         dp[i] = (dp[i] + dp[i - 1]) % mod;
  76.     }
  77.     cout << (dp[k] + mod) % mod;
  78. }
  79.  
  80. void Solve(){
  81.     Matrix ans, cur;
  82.     //memset(dp, 0, sizeof dp);
  83.     dp[0] = 1;
  84.     for(int i = 1; i < sz; ++i){
  85.         cur.a[sz - 1][sz - i] = (cur.a[sz - 1][sz - i] + s[i]) % mod;
  86.         cur.a[sz - 1][sz - i - 1] = (cur.a[sz - 1][sz - i - 1] - s[i]) % mod;
  87.         for(int j = 1; j <= i; ++j){
  88.             dp[i] = (dp[i] + s[j] * dp[i - j] % mod ) % mod;
  89.             if(i != j)
  90.                 dp[i] = (dp[i] - s[j] * dp[i - j - 1]) % mod;
  91.         }
  92.         dp[i] = (dp[i] + dp[i - 1]) % mod;
  93.         ans.a[i][1] = dp[i];
  94.         cur.a[i][i + 1] = 1;
  95.     }
  96.     ++cur.a[sz - 1][sz - 1];
  97.     cur = Pow(cur, k - 1ll) * ans;
  98.     cout << (cur.a[1][1] + mod) % mod;
  99. }
  100.  
  101. signed main(){
  102.     ios_base::sync_with_stdio(0);
  103.     cin.tie(0);
  104.     cout.tie(0); if(fopen(task".INP", "r"))
  105.     freopen(task".INP", "r", stdin),
  106.     freopen(task".OUT", "w", stdout);
  107.     Read();
  108.     Solve();
  109. }
Advertisement
Add Comment
Please, Sign In to add comment