uva 10375 筛法,组合数

该博客介绍了如何解决UVA 10375编程问题,涉及数论和筛法。问题要求计算不取模的分数(pq)/(rs),其中p, q, r, s的值小于等于10000,并确保p >= q, r >= s,结果不超过1e8。博主指出直接计算可能会导致溢出,但提供了易于理解的优化代码,其时间复杂度为O(n * n * sqrt(n))。" 109930181,10297029,Python pip卸载教程:轻松卸载已安装包,"['Python', 'pip']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 题意:

    • 给定p,q,r,s
    • 求{.5f}小数 (pq)/(rs)
  • 规模:

    • p,q,r,s<=10000
    • p>=q,r>=s
    • result<=1e8
  • 类型:

    • 数论,筛法
  • 分析:

    • 主要没有取模,直接做容易溢出
    • 代码很好理解
  • 时间复杂度&&优化:

    • O( nn )
  • 代码:

#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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值