NC15492. Youhane Generator -Real Model-
描述
祝你一发抽到PUR∠( ᐛ 」∠)_(图片来自Twitter@bemanistyle)优酱最近痴迷于KONMAI某街机音(抽)乐(卡)游戏Music Voltex Heavenly Haven,这个游戏除了可以给人带来爽上天的1600%疾走感之外,最为吸引人的就是可以以60块钱5张的价格抽取现场印刷的真实的卡片。虽然优酱的游戏水平非常低,但这并没有影响她抽卡的热情,毕竟一次性往街机里投60个币同时享受别人看智障的眼神,也是非常有爽快感的。
输入描述
单文件,多数据,请循环读取到文件末尾。
对于每组数据:
* 第一行为两个整数和,用空格分割,含义和范围范围请参见题目描述。
* 第二行为个整数,用空格分割,表示,含义和范围请参见题目描述。
我们保证数据中没有多余不可见字符。
输出描述
对于每组数据,请输出一个整数,表示答案,独占一行。
示例1
输入:
10 3 1 2 3
输出:
4083
C++14(g++5.4) 解法, 执行用时: 2883ms, 内存消耗: 616K, 提交时间: 2020-05-01 11:34:30
#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=1000000007; 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;} int _,n; namespace linear_seq { const int N=10010; ll res[N],base[N],_c[N],_md[N]; vector<int> Md; void mul(ll *a,ll *b,int k) { rep(i,0,k+k) _c[i]=0; rep(i,0,k) if (a[i]) rep(j,0,k) _c[i+j]=(_c[i+j]+a[i]*b[j])%mod; for (int i=k+k-1;i>=k;i--) if (_c[i]) rep(j,0,SZ(Md)) _c[i-k+Md[j]]=(_c[i-k+Md[j]]-_c[i]*_md[Md[j]])%mod; rep(i,0,k) a[i]=_c[i]; } int solve(ll n,VI a,VI b) { // a 系数 b 初值 b[n+1]=a[0]*b[n]+... // printf("%d\n",SZ(b)); ll ans=0,pnt=0; int k=SZ(a); assert(SZ(a)==SZ(b)); rep(i,0,k) _md[k-1-i]=-a[i];_md[k]=1; Md.clear(); rep(i,0,k) if (_md[i]!=0) Md.push_back(i); rep(i,0,k) res[i]=base[i]=0; res[0]=1; while ((1ll<<pnt)<=n) pnt++; for (int p=pnt;p>=0;p--) { mul(res,res,k); if ((n>>p)&1) { for (int i=k-1;i>=0;i--) res[i+1]=res[i];res[0]=0; rep(j,0,SZ(Md)) res[Md[j]]=(res[Md[j]]-res[k]*_md[Md[j]])%mod; } } rep(i,0,k) ans=(ans+res[i]*b[i])%mod; if (ans<0) ans+=mod; return ans; } VI BM(VI s) { VI C(1,1),B(1,1); int L=0,m=1,b=1; rep(n,0,SZ(s)) { ll d=0; rep(i,0,L+1) d=(d+(ll)C[i]*s[n-i])%mod; if (d==0) ++m; else if (2*L<=n) { VI T=C; ll c=mod-d*powmod(b,mod-2)%mod; while (SZ(C)<SZ(B)+m) C.pb(0); rep(i,0,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod; L=n+1-L; B=T; b=d; m=1; } else { ll c=mod-d*powmod(b,mod-2)%mod; while (SZ(C)<SZ(B)+m) C.pb(0); rep(i,0,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,0,SZ(c)) c[i]=(mod-c[i])%mod; return solve(n,c,VI(a.begin(),a.begin()+SZ(c))); } }; ll kv[1100]; int jc[5100]; int main() { int T; ll n,k; vector<int>v; jc[0]=jc[1]=1; for(int i=2;i<=5000;i++)jc[i]=1LL*i*jc[i-1]%mod; while (scanf("%lld%lld",&n,&k)==2) { v.clear(); for(int i=0;i<k;i++)scanf("%lld",&kv[i]); for(int i=0;i<=min(5000LL,n);i++){ if(i<k)v.push_back(1); else{ int res=1LL*jc[i]*powmod(jc[i-k],mod-2)%mod*powmod(jc[k],mod-2)%mod; for(int j=0;j<k;j++){ res=(res+1LL*kv[j]*v[i-1-j]%mod)%mod; //printf(",res=%d,%lld\n",v[i-1-j],kv[i]); } v.push_back(res); } } printf("%d\n",linear_seq::gao(v,n)); } }
C++11(clang++ 3.9) 解法, 执行用时: 3103ms, 内存消耗: 604K, 提交时间: 2019-03-13 01:49:14
#include<bits/stdc++.h> using namespace std; const int N = 4e3 + 7; typedef long long ll; const int mod = 1e9 + 7; ll F[N], invF[N]; ll C(int n, int m) { if(n < m || m < 0) return 0; return F[n] * invF[m] % mod * invF[n - m] % mod; } ll power_mod(ll a, ll b) { ll ret = 1; for(a %= mod; b; b >>= 1, a = a * a % mod) if(b & 1) ret = ret * a % mod; return ret; } int n, k; ll a[N], b[N], c[N], _c[N], res[N]; void mul(ll *a, ll *b, ll *md, int L) { for(int i = 0; i < 2 * L; i++) _c[i] = 0; for(int i = 0; i < L; i++) for(int j = 0; j < L; j++) (_c[i + j] += a[i] * b[j]) %= mod; for(int i = 2 * L - 2; i >= L; i--) for(int j = 0; j < L; j++) (_c[i - j - 1] += _c[i] * md[j]) %= mod; for(int i = 0; i < L; i++) a[i] = _c[i]; } ll solve(ll *res, ll *r, int n, int L) { int pn = 0; ll ret = 0; while((1<<pn) <= n) pn++; pn--; for(int i = 0; i < L; i++) res[i] = 0; res[0] = 1; for(int i = pn; ~i; i--) { mul(res, res, b, L); if(n>>i&1) { for(int i = L - 1; ~i; i--) res[i + 1] = res[i]; res[0] = 0; for(int i = 0; i < L; i++) (res[L - 1 - i] += res[L] * b[i]) %= mod; } } for(int i = 0; i < L; i++) (ret += r[i] * res[i]) %= mod; return ret; } int main() { #ifdef local freopen("in.txt", "r", stdin); #endif F[0] = invF[0] = 1; for(int i = 1; i < N; i++) F[i] = F[i - 1] * i % mod; invF[N - 1] = power_mod(F[N - 1], mod - 2); for(int i = N - 2; i; i--) invF[i] = invF[i + 1] * (i + 1) % mod; while(~scanf("%d%d", &n, &k)) { for(int i = 1; i <= k; i++) { scanf("%lld", a + i); if(a[i] < 0) a[i] += mod; } int m = 2 * k + 1; for(int i = 0; i <= m; i++) b[i] = 0; int sign = 1; for(int i = k - 1; ~i; i--, sign = mod - sign) b[i + k] = sign * C(k, i) % mod; sign = 1; for(int i = k; ~i; i--, sign = mod - sign) { ll tt = sign * C(k, i) % mod; for(int j = 1; j <= k; j++) (b[i + k - j] += tt * a[j]) %= mod; } b[m - 1] = -1; for(int i = m - 1; i; i--) b[i] = (b[i - 1] + mod - b[i]) % mod; b[0] = (mod - b[0]) % mod;; reverse(b, b + m); for(int i = 0; i < m; i++) { if(i < k) c[i] = 1; else { c[i] = C(i, k); for(int j = 1; j <= k; j++) (c[i] += c[i - j] * a[j]) %= mod; } } printf("%lld\n", solve(res, c, n, m)); } return 0; }