uva10375 Choose and divide

唯一分解定理。

挨个记录下每个质数的指数。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn = 100000 + 10;
typedef long long LL;

double ans;
int p,q,s,t;
bool mark[maxn];
int prime[maxn],cnt;
int f[maxn];

void get_prime() {
    for(int i=2;i<=10000;i++) {
        if(!mark[i]) prime[++cnt]=i;
        for(int j=1;j<=cnt;j++) {
            int t=prime[j]*i;
            if(t>10000) break;
            mark[t]=1;
            if(i%prime[j]==0) break;    
        }
    }
}

inline void work(int n,int d) {
    for(int i=1;i<=cnt;i++) if(!(n%prime[i])) {
        while(!(n%prime[i])) {
            n/=prime[i];
            f[i]+=d;
        }
        if(n==1) break;
    }
}

inline void add(int m,int n,int d) {
    for(int i=m;i<=n;i++) work(i,d);    
}

int main() {
    get_prime();
    while(scanf("%d%d%d%d",&p,&q,&s,&t)==4) {
        memset(f,0,sizeof(f));        
        add(q+1,p,1);
        add(1,p-q,-1);
        add(t+1,s,-1);
        add(1,s-t,1);
        ans=1;
        //for(int i=1;i<=cnt;i++) if(f[i]) {
        //    if(f[i]>0) for(int j=1;j<=f[i];j++) ans*=prime[i];
        //        else for(int j=1;j<=-f[i];j++) ans/=prime[i];
        //    }
        for(int i=1;i<=cnt;i++) if(f[i]) ans*=pow(prime[i],f[i]);
        printf("%.5lf\n",ans);
    }
    return 0;
}
posted @ 2016-06-10 13:17  invoid  阅读(141)  评论(0编辑  收藏  举报