Title:
Have nnn numbersa 1, 2,.. n a_{1,2,..n}a1,2,..n, Your initial energy is a 0 a_0a0, Each time you can only select the number less than or equal to the current energy, after selecting the number ai a_iaiAfter the current energy will add ai a_iai, Find the number of plans after selecting all numbers mod 1 e 9 + 7 mod\ 1e9+7m o d 1 e 9 +7
n ≤ 1 e 5, 0 ≤ ai ≤ 50 n \ le1e5,0 \ le a_i \ le 50n≤1e5,0≤ai≤50
Problem-solving ideas:
Notice ai a_iaiVery small, the current energy exceeds ai a_iaiAfter the upper limit, you can choose at will. So we can consider direct memory search, pay attention to picking out 0 alone.
The number of search nodes = the number of divisions of 50 = 204226 The number of search nodes = the number of divisions of 50 = 204226Search Cable junction point number mesh=. 5 0 The classified fraction number=2 0 4 2 2 6 .
The current search state can be hashed and stored in unorder_map, or you can write a hash to store it yourself. The direct map structure will time out, and the map hash value will also time out.
ComplexityO (f (50) ∗ 50 ∗ Average search time of mapping function) O(f(50)*50* Average search time of mapping function)O(f(50)∗50∗Mapping radio function number level average search to find the time between )
AC codes:
#include<bits/stdc++.h>
#define ll long long
#define lowbit(x) ((x)&(-(x)))
#define mid ((l+r)>>1)
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
#define ull unsigned long long
using namespace std;
const int mod = 1e9 + 7;
struct node{
int a[51];
node(){
memset(a,0,sizeof a);}
};
const int maxn = 1e5 + 50;
int fac[maxn], ifac[maxn];
int qm(int a, int b){
int res = 1;
while(b){
if(b&1) res = (ll)res*a%mod;
a = (ll)a*a%mod;
b >>= 1;
}return res;
}
int n;
unordered_map<ull,int> mp;
ull sed = 131;
ull p[55];
node state;
int dp(int cur, int res){
if(res == 0) return 1;
if(cur >= 50){
return fac[res];
}
ull ha = 0;
for(int i = 50; i > 0; --i) ha = ha*sed+state.a[i];
if(mp.find(ha) != mp.end()) return mp[ha];
int ans = 0;
for(int i = 1; i <= cur; ++i){
if(!state.a[i]) continue;
int t = state.a[i];
--state.a[i];
ans = (ans+(ll)t*dp(cur+i, res-1)%mod)%mod;
++state.a[i];
}
mp[ha] = ans;
return ans;
}
int main()
{
p[0] = 1; for(int i = 1; i < 55; ++i) p[i] = p[i-1]*sed;
fac[0] = ifac[0] = 1;
for(int i = 1; i < maxn; ++i) fac[i] = (ll)fac[i-1]*i%mod;
ifac[maxn-1] = qm(fac[maxn-1], mod-2);
for(int i = maxn-2; i > 0; --i) ifac[i] = (ll)ifac[i+1]*(i+1)%mod;
scanf("%d", &n);
int cur, num = 0, z = 0; scanf("%d", &cur);
for(int i = 1; i <= n; ++i){
int x; scanf("%d", &x);
if(x == 0) z++;
else state.a[x]++, num++;
}
int ans = dp(cur, num);
ans = (ll)ans * (ll)fac[n]%mod*(ll)ifac[n-z]%mod;
cout<<ans<<endl;
}