题意:
- 给定p,q,r,s
- 求{.5f}小数 (pq)/(rs)
规模:
- p,q,r,s<=10000
- p>=q,r>=s
- result<=1e8
类型:
- 数论,筛法
分析:
- 主要没有取模,直接做容易溢出
- 代码很好理解
时间复杂度&&优化:
- O( n∗n√ )
代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<algorithm>
#include<iostream>
using namespace std;
const int INF=0x3fff3fff;
const int MAXN=1e6+10;
const int MAXM=40010;
const int MOD=10001;
typedef long long ll;
//*********************
//素数筛和合数分解
/*
* prime[0]为[2~MAXN]素数个数
* prime[1]=2,prime[2]=3,prime[3]=5````
* 线性筛O(n)
*
* getFactors
* 返回质因子个数,factor[0~fact)有效
* factor[i][0]表示升序第i个质因子的值
* factor[i][1]表示对应的指数
* 不能多次使用,每次结果必须提出来
*/
int prime[MAXN+1];
int is_prime[MAXN+1];
void getPrime(){
memset(prime,0,sizeof(prime));
for(int i=2;i<=MAXN;i++){
if(!prime[i]){prime[++prime[0]]=i;is_prime[i]=1;}
for(int j=1;j<=prime[0]&&prime[j]<=MAXN/i;j++){
prime[prime[j]*i]=1;
if(i%prime[j]==0)break;
}
}
}
long long factor[100][2];
int fatCnt;
int getFactors(long long x){
fatCnt=0;
long long tmp=x;
for(int i=1;prime[i]<=tmp/prime[i];i++)
{
factor[fatCnt][1]=0;
if(tmp%prime[i]==0){
factor[fatCnt][0]=prime[i];
while(tmp%prime[i]==0){
factor[fatCnt][1]++;
tmp/=prime[i];
}
fatCnt++;
}
}
if(tmp!=1){
factor[fatCnt][0]=tmp;
factor[fatCnt++][1]=1;
}
return fatCnt;
}
int e[MAXN];
void add_factor(int n,int d){
getFactors(n);
for(int i=0;i<fatCnt;i++){
//cout<<factor[i][0]<<endl;
e[factor[i][0] ]+=d*factor[i][1];
}
}
int n,m;
//long long x[2100];
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
long long p,q,r,s;
getPrime();
while(cin>>p>>q>>r>>s){
memset(e,0,sizeof(e));
for(int i=1;i<=p;i++)add_factor(i,1);
for(int i=1;i<=q;i++)add_factor(i,-1);
for(int i=1;i<=p-q;i++)add_factor(i,-1);
for(int i=1;i<=r;i++)add_factor(i,-1);
for(int i=1;i<=s;i++)add_factor(i,1);
for(int i=1;i<=r-s;i++)add_factor(i,1);
double ans = 1.0;
for(int i=1;i<MAXN;i++){
if(is_prime[i])ans*=pow(i,e[i]);
}
printf("%.5f\n",ans);
}
return 0;
}