1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
| #include<bits/stdc++.h> using namespace std;
#define Mod1(x) ((x>=P)&&(x-=P)) #define Mod2(x) ((x<0)&&(x+=P))
#define reg register typedef long long ll; #define rep(i,a,b) for(reg int i=a,i##end=b;i<=i##end;++i) #define drep(i,a,b) for(reg int i=a,i##end=b;i>=i##end;--i)
#define pb push_back template <class T> inline void cmin(T &a,T b){ ((a>b)&&(a=b)); } template <class T> inline void cmax(T &a,T b){ ((a<b)&&(a=b)); }
char IO; int rd(){ int s=0; int f=0; while(!isdigit(IO=getchar())) if(IO=='-') f=1; do s=(s<<1)+(s<<3)+(IO^'0'); while(isdigit(IO=getchar())); return f?-s:s; }
const int N=50,P=1e9+7;
ll qpow(ll x,ll k=P-2) { ll res=1; for(;k;k>>=1,x=x*x%P) if(k&1) res=res*x%P; return res; }
int n,m;
struct Mat{ int a[N][N]; Mat(){ memset(a,0,sizeof a); } int Det(int n){ static int G[N][N]; rep(i,1,n) rep(j,1,n) G[i][j]=a[i][j]; int res=1; rep(i,1,n) { if(!G[i][i]) rep(j,i+1,n) if(G[j][i]){ res=P-res; swap(G[i],G[j]); break; } if(!G[i][i]) continue; ll Inv=qpow(a[i][i]); rep(j,i+1,n) { ll t=a[j][i]*Inv%P; rep(k,i,n) a[j][k]=(a[j][k]-1ll*a[i][k]*t%P+P)%P; } } rep(i,1,n) res=1ll*res*a[i][i]%P; return res; } };
int w[N],G[N][N],C[N][N]; void Init(){ rep(i,0,N-1) rep(j,C[i][0]=1,i) C[i][j]=(C[i-1][j-1]+C[i-1][j])%P; rep(i,0,n) { Mat T; rep(j,1,m) { rep(k,1,n+m) T.a[j][k]=-1; T.a[j][j]=n+m-1; } rep(j,m+1,m+i) { rep(k,1,m+i) if(j!=k) T.a[j][k]=-1; T.a[j][j]=m+i-1; } rep(j,m+i+1,m+n) { rep(k,1,m) T.a[j][k]=-1; T.a[j][j]=m; } w[i]=T.Det(n+m-1); } rep(i,0,n) rep(j,0,i-1) w[i]=(w[i]-1ll*C[i][j]*w[j]%P+P)%P; }
int val[N]; vector <int> st[N/2];
int Meet_In_The_Middle(int Max){ int ans=0,mid=n/2; rep(i,0,mid) st[i].clear(); rep(S,0,(1<<mid)-1) { int c=0,s=0; rep(i,0,mid-1) if(S&(1<<i)) s+=val[i],c++; if(s<=Max) st[c].pb(s); } rep(i,0,mid) sort(st[i].begin(),st[i].end()); rep(S,0,(1<<(n-mid))-1) { int c=0,s=0; rep(i,0,n-mid-1) if(S&(1<<i)) s+=val[i+mid],c++; if(s>Max) continue; rep(j,0,mid) { int x=upper_bound(st[j].begin(),st[j].end(),Max-s)-st[j].begin(); if(x) ans=(ans+1ll*x*w[c+j])%P; } } return ans; }
class SweetFruits { public: int countTrees(vector <int> Val, int Max) { sort(Val.begin(),Val.end(),greater <int> ()); m=0; while(Val.size() && *Val.rbegin()==-1) m++,Val.pop_back(); n=Val.size(); rep(i,0,n-1) val[i]=Val[i]; Init(); return Meet_In_The_Middle(Max); } };
|