标签:turn iostream kill skill vector 次数 typedef str 质数
一列火车n节车厢,依次编号为1,2,3,…,n。
每节车厢有两种运动方式,进栈与出栈,问n节车厢出栈的可能排列方式有多少种。
输入格式
输入一个整数n,代表火车的车厢数。
输出格式
输出一个整数s表示n节车厢出栈的可能排列方式数量。
数据范围
1≤n≤60000
输入样例:
3
输出样例:
5
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
const int N=120010;
int powers[N];//每个质数的次数
int primes[N],cnt;/质数表2~2*n内的质数
bool st[N];//用来储存这个数是不是质数
typedef long long ll;
void get_primes(int n)//筛法判断是不是质数
{
for(int i=2;i<=n;i++)
if(!st[i])
{
primes[cnt++]=i;
for(int j=i*2;j<=n;j+=i)
st[j]=true;
}
}
int get(int n,int p)//n的阶乘里有多少个因子p
{
ll s=0;
while(n)
{
s+=n/p;
n/=p;
}
return s;
}
void multi(vector<ll>&a,int b)//压位高精度运算
{
int t=0;
for(int i=0;i<a.size();i++)
{
a[i]=a[i]*b+t;
t=a[i]/100000000;
a[i]%=100000000;
}
while(t)
{
a.push_back(t%100000000);
t/=100000000;
}
}
void out(vector<ll >&a)//输出
{
printf("%lld",a.back());
for(int i=a.size()-2;i>=0;i--)
printf("%08lld",a[i]);
cout<<endl;
}
int main()
{
int n;
cin>>n;
get_primes(n*2);
for(int i=0;i<cnt;i++)//分别求一下质数的次数
{
int p=primes[i];
powers[p]=get(n*2,p)-get(n,p)*2;//(C2n n)是2n的阶乘除以(n的阶乘*n的阶乘),所以乘2
}
int k=n+1;//分解质因数
for(int i=0;i<cnt&&primes[i]<=k;i++)
{
int p=primes[i],s=0;
while(k%p==0)
{
s++;
k/=p;
}
powers[p]-=s;
}
vector<ll>res;
res.push_back(1);
for(int i=2;i<=n*2;i++)
for(int j=0;j<powers[i];j++)
multi(res,i);
out(res);
return 0;
}
这个代码又是yxc大佬的源代码基础上写的注释,我还是太菜了。QAQ
标签:turn iostream kill skill vector 次数 typedef str 质数
原文地址:https://www.cnblogs.com/arbor-one/p/12255202.html