A bank allows two methods of login:
The bank wants to know how many distinct IDs they can provide such that no two users have access to the same account.
The input contains a single integer $n$ $(1 \leq n \leq 10^6)$.
Print a single integer, the answer to the problem modulo $1000000007$ ($10^9 + 7$).
Input | Output |
---|---|
1 Copy
|
12 Copy
|
2 Copy
|
54 Copy
|
3 Copy
|
174 Copy
|
The main idea of the solution is to add a new rule on the id to make it unique for each product.
We chose to count the shortest id for each product, by the shortest id we mean the id that contains the least amount of non $1$
numbers.
To make an id the shortest possible we should prioritize $10$ and $9$ then $8$ then $4$ then $6$ then $3$ and $2$, while $11$ and $7$ can be repeated any number of times.
$10$ takes the highest priority since it's only affected by 8 only and $3$ $10s$ are better than $3$ $5s$ and $1$ $8$.
$4$ and $6$ are equivalent so you can prioritize any.
$6$, $4$, $3$, $2$ can only be repeated $1$ each since repeating more than once will create a new case.
$5$ can be repeated any number of times while there is no even number in the id.
By applying the aforementioned rule we have the following cases:
#include <bits/stdc++.h>
using namespace std;
const int M = 1e9 + 7,N = 2e6 + 5;
mt19937_64 rng(std::chrono::system_clock::now().time_since_epoch().count());
int n,ans = 1,fact[N] = {1},inv[N];
void add(int &a,int b){
a+=b;
if(a >= M)a-=M;
if(a < 0)a+=M;
}
int power(int base,int to){
int ret = 1;
while(to){
if(to&1)ret = ret*1LL*base%M;
to>>=1;
base = base*1LL*base%M;
}
return ret;
}
int choose(int n,int k){
if(n < k)return 0;
return (fact[n]*1LL*inv[k]%M)*inv[n - k]%M;
}
int find(int n){
if(!n)return 1;
////1* 5* 7* 9* 10* 11*
int ret = choose(n + 5,5);
////1* 7* 8+ 9* 10* 11*
add(ret,choose(n + 4,5));
////1* 3 5* 7* 9* 10* 11*
add(ret,choose(n + 4,5));
////1* 3 7* 8+ 9* 10* 11*
if(n > 1)add(ret,choose(n + 3,5));
////1* (2|4|6) 7* 8* 9* 10* 11*
add(ret,3LL*choose(n + 4,5)%M);
////1* 3 4 7* 8* 9* 10* 11*
if(n > 1)add(ret,choose(n + 3,5));
return ret;
}
int main(){
// freopen("input.txt","r",stdin);
for(int i = 1;i < N;i++)fact[i] = fact[i - 1]*1LL*i%M;
inv[N - 1] = power(fact[N - 1],M - 2);
for(int i = N - 2;i + 1;i--)inv[i] = inv[i + 1]*(i + 1LL)%M;
cin >> n;
cout << find(n) + 1 << endl;
}