POJ2992 Divisors 因子和因子个数的应用

来源:互联网 发布:河北网络卫视在线直播 编辑:程序博客网 时间:2024/05/10 17:56

本题过题率并不是很高,只有百分之三十不到的样子,数字很大,看着比较吓人的,

由于k与n很大,求组合数 肯定不可能,所以要先求约数有多少个,直接进行素因子分解,因为组合数其实 是有公式 的 可以写成阶乘的形式,因此先对阶乘进行素因子分解

1.看看题目的数据范围,大概筛选500以内的素数就可以了

2.然后对每隔阶乘进行素因子分解

3.求出组合输的素因子分解而后便可得到约数的个数;


#include<iostream>#include<cstdio>#include<list>#include<algorithm>#include<cstring>#include<string>#include<queue>#include<stack>#include<map>#include<vector>#include<cmath>#include<memory.h>#include<set>#define ll long long#define eps 1e-8#define inf 0xfffffffconst ll INF = 1ll<<61;using namespace std;//vector<pair<int,int> > G;//typedef pair<int,int > P;//vector<pair<int,int> > ::iterator iter;////map<ll,int >mp;//map<ll,int >::iterator p;//bool vis[502];int a[102],cnt;int divide[502][102];ll ans[502][502];void clear(){memset(divide,0,sizeof(divide));memset(ans,0,sizeof(ans));memset(vis,false,sizeof(vis));memset(a,0,sizeof(a));cnt=0;}void init(){clear();vis[0]=vis[1]=false;for(int i=2;i<500;i++){if(!vis[i])a[cnt++]=i;for(int j=0;j<cnt && i*a[j] < 500;j++){vis[i*a[j]] = 1;if(!(i%a[j]))break;}}for(int i=0;i<cnt;i++)for(int j=2;j<500;j++)divide[j][i]=j/a[i]+divide[j/a[i]][i];for(int i=2;i<500;i++){for(int j=1;j<i;j++){ans[i][j]=1;for(int k=0;k<cnt && divide[i][k];k++){int mark=divide[i][k]-divide[j][k]-divide[i-j][k];if(mark)ans[i][j]*=(mark+1);//此处可以求出因子的个数}}}}int main(){init();int n,k;while(cin>>n>>k){if(k==0 || n==k){puts("1");continue;}cout<<ans[n][k]<<endl;}return EXIT_SUCCESS;}


1 0
原创粉丝点击