当前位置:网站首页>Principle of finding combinatorial number and template code
Principle of finding combinatorial number and template code
2022-07-02 01:06:00 【Alkali!】
Type 1 : Put C Array preprocessing ( Recurrence )
Background
Ideas
According to the combination number recurrence formula , First The number of combinations to be used in the range is pre processed and tabulated
C a b = C a − 1 b + C a − 1 b − 1 C_{a}^{b}=C_{a-1}^{b}+C_{a-1}^{b-1} Cab=Ca−1b+Ca−1b−1
prove :
stay a Take from one ball b A ball , How many ways are there ?
Yes C a b C_{a}^{b} Cab Kind of
You can think of a ball c Very special , Then take b There are two ways to get a ball : Fetch c Still don't get it c
Fetch c: C a − 1 b − 1 C_{a-1}^{b-1} Ca−1b−1( In addition a-1 Take from one ball b-1 individual )
Can't get c: C a − 1 b C_{a-1}^{b} Ca−1b( stay a-1 Take... From a ball b individual )
// Background :AcWing 885
#include<iostream>
using namespace std;
const int N=2010,mod=1e9+7;
int c[N][N];
void init()
{
for(int i=0;i<N;i++) //N Is the upper limit of the subscript of the combinatorial number
for(int j=0;j<=i;j++)
if(!j) c[i][j]=1; // If the superscript is 0, That means not taking any , There is only one case , Note that this is not 0, It is 1
else c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod; // Take the mold when calculating
}
Template code
// Background :AcWing 885
#include<iostream>
using namespace std;
const int N=2010,mod=1e9+7;
int c[N][N];
void init()
{
for(int i=0;i<N;i++)
for(int j=0;j<=i;j++)
if(!j) c[i][j]=1;
else c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
}
int main()
{
init();
int n,a,b;
scanf("%d",&n);
while(n--)
{
scanf("%d%d",&a,&b);
printf("%d\n",c[a][b]);
}
return 0;
}
Type 2 : Preprocessing out factorials
Background
Ideas
- Why does this problem require an inverse element , Can't you just divide by the corresponding factorial ?
Template code
// Background AcWing 886
#include<iostream>
using namespace std;
const int N=100010,mod=1e9+7;
typedef long long LL;
int fact[N],infact[N];
int n,a,b;
int qmi(int a,int b,int p) // Fast power algorithm
{
int res=1;
while(b)
{
if(b&1) res=(LL)res*a%p;
a=(LL)a*a%p;
b=b>>1;
}
return res;
}
int main()
{
fact[0]=1,infact[0]=1;
for(int i=1;i<N;i++) // Preprocess factorials and inverse elements of factorials
{
fact[i]=(LL)fact[i-1]*i%mod;
infact[i]=(LL)infact[i-1]*qmi(i,mod-2,mod)%mod;
}
scanf("%d",&n);
while(n--)
{
scanf("%d%d",&a,&b);
printf("%d\n",(LL)fact[a]*infact[b]%mod*infact[a-b]%mod);
}
return 0;
}
(LL) On the left are int value , Explain to confirm The end result is a int Values in range , Because in the end, it's all molded mod Yes ! But in the specific calculation process, multiplication first may explode int, If you use int Saving may lead to data errors , So here (LL) The function of should be Temporarily store the data in LL Within the range of , To ensure correctness , Finally get another int Result .
Type 3 : Use Lucas theorem to recursively narrow the scope
Background
The upper and lower limits of the combination number are particularly large
Ideas
utilize lucas Theorem to simplify calculation
lucas Theorem content :
Use Lucas theorem to recurse downward , hold a、b Reduce to scale p Small number , Then calculate the factorial directly .
Time complexity :
Template code
// Background :AcWing 887
#include<iostream>
using namespace std;
typedef long long LL;
int n,p;
LL a,b;
int qmi(int a,int b,int p) // Fast power algorithm
{
int res=1;
while(b)
{
if(b&1) res=(LL)res*a%p;
a=(LL)a*a%p;
b=b>>1;
}
return res;
}
int C(int a,int b,int p) // Directly calculate the number of combinations
{
if(b>a) return 0;
int res=1;
for(int i=1,j=a;i<=b;i++,j--)
{
res=(LL)res*j%p;
res=(LL)res*qmi(i,p-2,p)%p;
}
return res;
}
int lucas(LL a,LL b,int p) // Lucas theorem
{
if(a<p&&b<p) return C(a,b,p);
else return (LL)C(a%p,b%p,p)*lucas(a/p,b/p,p)%p;
}
int main()
{
scanf("%d",&n);
while(n--)
{
scanf("%lld%lld%d",&a,&b,&p);
printf("%d\n",lucas(a,b,p));
}
return 0;
}
Type four : Calculate the number accurately , No more mold taking ( High precision multiplication )
Background
Ideas
First, we decompose the prime factor , Then use high-precision multiplication to calculate this combined number .
Specific steps :
- 1. hold 1 − a 1-a 1−a Sift out all primes between ( Linear sieve method )
void get_primes(int n)
{
for(int i=2;i<=n;i++)
{
if(!st[i])primes[cnt++]=i;
for(int j=0;primes[j]*i<=n;j++)
{
st[primes[j]*i]=true;
if(i%primes[j]==0)break;//==0 Every leak
}
}
}
- To calculate the C a b C_{a}^{b} Cab in 1 − a 1-a 1−a How many primes do they contain
principle :
int get(int n,int p)
{
int res =0;
while(n)
{
res+=n/p;
n/=p;
}
return res;
}
// In the main function
for(int i=0;i<cnt;i++)
{
int p = primes[i];
sum[i] = get(a,p)-get(a-b,p)-get(b,p);
}
- Multiply all prime factors with high precision
vector<int> mul(vector<int> a, int b)
{
vector<int> c;
int t = 0;
for (int i = 0; i < a.size(); i ++ )
{
t += a[i] * b;
c.push_back(t % 10);
t /= 10;
}
while (t)
{
c.push_back(t % 10);
t /= 10;
}
return c;
}
// In the main function
vector<int> res;
res.push_back(1);
for (int i = 0; i < cnt; i ++ )
for (int j = 0; j < sum[i]; j ++ )//primes[i] The number of times
res = mul(res, primes[i]);
- Output the answer
for (int i = res.size() - 1; i >= 0; i -- ) printf("%d", res[i]);
Template code
#include<iostream>
#include<vector>
using namespace std;
int a,b;
const int N=5010;
int primes[N],cnt,sum[N];
bool st[N];
void get_primes(int n) // Linear sieve method
{
for(int i=2;i<=n;i++)
{
if(!st[i]) primes[cnt++]=i;
for(int j=0;primes[j]<=n/i;j++)
{
st[primes[j]*i]=true;
if(i%primes[j]==0) break;
}
}
}
int get(int n,int p) // Calculate the number of times the prime number appears
{
int res=0;
while(n)
{
res+=n/p;
n/=p;
}
return res;
}
vector<int> mul(vector<int> a,int b) // High precision multiplication
{
// here b Definitely not for 0
vector<int> c;
int t=0;
for(int i=0;i<a.size()||t;i++)
{
if(i<a.size()) t+=a[i]*b;
c.push_back(t%10);
t/=10;
}
return c;
}
int main()
{
scanf("%d%d",&a,&b);
get_primes(a); // Sieve prime number
for(int i=0;i<cnt;i++) // Calculate the number of prime occurrences
{
int p=primes[i];
sum[i]=get(a,p)-get(b,p)-get(a-b,p);
}
vector<int> res;
res.push_back(1); // The initial value of the assignment is 1
// Decomposing prime factor , The prime factor is obtained , We also get the number of times of each prime factor , At this time, multiply them repeatedly , Use high-precision multiplication to calculate
for(int i=0;i<cnt;i++)
for(int j=0;j<sum[i];j++)
res=mul(res,primes[i]);
for(int i=res.size()-1;i>=0;i--) printf("%d",res[i]);
return 0;
}
边栏推荐
- Recently, three articles in the nature sub Journal of protein and its omics knowledge map have solved the core problems of biology
- Global and Chinese market of aircraft MRO software 2022-2028: Research Report on technology, participants, trends, market size and share
- Datawhale community blackboard newspaper (issue 1)
- Global and Chinese market of wireless chipsets 2022-2028: Research Report on technology, participants, trends, market size and share
- Export default the exported object cannot be deconstructed, and module Differences between exports
- 2022 low voltage electrician examination questions and answers
- How does schedulerx help users solve the problem of distributed task scheduling?
- Summary of Aix storage management
- Excel PivotTable
- Global and Chinese market of collaborative applications 2022-2028: Research Report on technology, participants, trends, market size and share
猜你喜欢
How can entrepreneurial teams implement agile testing to improve quality and efficiency? Voice network developer entrepreneurship lecture Vol.03
What skills does an excellent software tester need to master?
教你白嫖Amazon rds一年并搭建MySQL云数据库(只需10分钟,真香)
gradle
King combat power query renamed toolbox applet source code - with traffic main incentive advertisement
969 interlaced string
2023 Lexus ES products have been announced, which makes great progress this time
You probably haven't noticed the very important testing strategy in your work
2022 safety officer-b certificate examination practice questions simulated examination platform operation
PLC Analog input analog conversion FB s_ ITR (Mitsubishi FX3U)
随机推荐
Deb file installation
The first "mobile cloud Cup" empty publicity meeting, looking forward to working with developers to create a new world of computing!
Develop a simple login logic based on SSM
How to open an account for individual stock speculation? Is it safe?
Slf4j print abnormal stack information
【底部弹出-选择器】uniapp Picker组件——底部弹起的滚动选择器
DTL dephossite | prediction method of dephosphorylation sites based on Transfer Learning
[wechat authorized login] the small program developed by uniapp realizes the function of obtaining wechat authorized login
【八大排序①】插入排序(直接插入排序、希尔排序)
Node -- egg creates a local file access interface
2022 low voltage electrician examination questions and answers
Upgraded wechat tool applet source code for mobile phone detection - supports a variety of main traffic modes
2022 pinduoduo details / pinduoduo product details / pinduoduo SKU details
AIX存储管理之总结篇
Datawhale community blackboard newspaper (issue 1)
449-原码、补码、反码
Xinniuniu blind box wechat applet source code_ Support flow realization, with complete material pictures
2022 safety officer-a certificate examination questions and online simulation examination
Excel PivotTable
Leetcode skimming: stack and queue 01 (realizing queue with stack)