21.6.13 t1
阿新 • • 發佈:2021-06-24
tag:揹包dp,插值
考場50分,對著資料懷疑人生一個小時,然後教練過來說資料掛了。。
然而下發的標程也掛了,又懷疑人生了一個小時。。
對於 \(40%\) 很容易就能想到列舉 \(m\),然後跑揹包dp。
仔細觀察這個dp是形如:
\[\sum_{S\subseteq\{1\cdots n\},|S|\ge k}(\prod_{i\not\in S}(a_im+b_i)\prod_{i\in S}(c_im+d_i)) \]所以答案一定是關於 \(m\) 的多項式。
然後插值。
#include<bits/stdc++.h> using namespace std; template<typename T> inline void Read(T &n){ char ch; bool flag=false; while(!isdigit(ch=getchar()))if(ch=='-')flag=true; for(n=ch^48;isdigit(ch=getchar());n=(n<<1)+(n<<3)+(ch^48)); if(flag)n=-n; } #define int long long typedef long long ll; enum{ MAXN = 55, MOD = 1000000007, }; int B; inline int ksm(int base, int k=MOD-2){ int res=1; while(k){ if(k&1) res = 1ll*res*base%MOD; base = 1ll*base*base%MOD; k >>= 1; } return res; } inline int inc(int a, int b){ assert(0<=a and a<MOD and 0<=b and b<MOD); a += b; if(a>=MOD) a -= MOD; return a; } inline int dec(int a, int b){ assert(0<=a and a<MOD and 0<=b and b<MOD); a -= b; if(a<0) a += MOD; return a; } inline void ddec(int &a ,int b){a = dec(a,b);} inline void iinc(int &a, int b){a = inc(a,b);} inline void upd(int &a, ll b){a = (a+b)%MOD;} int n, m, A, k; int x[MAXN], y[MAXN], d[MAXN], f[MAXN][MAXN]; namespace ChaZhi{ int x[MAXN<<1], y[MAXN<<1], mul[MAXN<<1], f[MAXN<<1], tmp[MAXN<<1]; inline void Interpolate(int n){ memset(mul,0,sizeof mul); memset(f,0,sizeof f); mul[0]=1; for(register int i=1; i<=n; i++){ for(register int j=i; j; j--) mul[j] = dec(mul[j-1],1ll*mul[j]*x[i]%MOD); mul[0] = dec(0,1ll*mul[0]*x[i]%MOD); } for(register int i=1; i<=n; i++){ ll S=1; for(register int j=1; j<=n; j++) if(i!=j) S = 1ll*S*dec(x[i],x[j])%MOD; S = 1ll*ksm(S)*y[i]%MOD; for(register int j=0; j<=n; j++) tmp[j]=mul[j]; for(register int j=n; j; j--) upd(tmp[j-1],1ll*tmp[j]*x[i]), upd(f[j-1],1ll*tmp[j]*S); } } inline int Calc(int n, int k){ int ans=0; for(register int i=n-1; i>=0; i--) ans=(1ll*ans*k+f[i])%MOD; return ans; } } using ChaZhi::Calc; using ChaZhi::Interpolate; int timepoint[MAXN*2], cnt; int tmp[MAXN<<1]; signed main(){ freopen("1.in","r",stdin); // freopen("11.out","w",stdout); Read(n); Read(m); Read(k); Read(A); B = n; for(register int i=1; i<=n; i++){ Read(d[i]), Read(x[i]), Read(y[i]), d[i] = max(1ll,A-d[i]); timepoint[++cnt] = (x[i]+d[i]-1)/d[i]; timepoint[++cnt] = y[i]/d[i]+1; } timepoint[++cnt] = m+1; timepoint[++cnt] = 1; sort(timepoint+1,timepoint+cnt+1); int sum=0; for(register int i=1; i<=cnt and timepoint[i]<=m; i++){ int dlt=0; for(register int t=timepoint[i]; t<timepoint[i+1] and dlt<B; t++){ dlt++; int ans=0; memset(f,0,sizeof f); f[0][0] = 1; for(register int j=1; j<=n; j++){ ll lim = 1ll*d[j]*t; if(lim<x[j]) for(register int p=0; p<j; p++) f[j][p] = 1ll*(y[j]-x[j]+1)*f[j-1][p]%MOD; else if(lim>=y[j]) for(register int p=0; p<j; p++) f[j][p+1] = 1ll*(y[j]-x[j]+1)*f[j-1][p]%MOD; else for(register int p=0; p<j; p++) upd(f[j][p],1ll*(y[j]-lim)*f[j-1][p]), upd(f[j][p+1],1ll*(lim-x[j]+1)*f[j-1][p]); } for(register int j=k; j<=n; j++) iinc(ans,f[n][j]); ChaZhi::x[dlt] = t; ChaZhi::y[dlt] = ans; } if(dlt<B) for(register int j=1; j<=dlt; j++) iinc(sum,ChaZhi::y[dlt]); else{ Interpolate(dlt); for(register int j=1; j<=dlt+1; j++) tmp[j] = Calc(dlt,j), iinc(tmp[j],tmp[j-1]); dlt++; for(register int j=1; j<=dlt; j++) ChaZhi::x[j] = j, ChaZhi::y[j] = tmp[j]; Interpolate(dlt); iinc(sum,Calc(dlt,timepoint[i+1]-1)); ddec(sum,Calc(dlt,timepoint[i]-1)); } } cout<<sum<<'\n'; return 0; }