uva 10375

  1  /*  选择与除法_________________________________________________________________________________
  2
  3                           #include <iostream>
  4                           #include <map>
  5                           #include <cmath>
  6                           #include <vector>
  7                           #include <cstdio>
  8                           #include <string>
  9                           #include <cstring>
 10                           #include <algorithm>
 11                           using namespace std;
 12                           #define fir first
 13                           #define sec second
 14                           #define pb(x) push_back(x)
 15                           #define mem(A, X) memset(A, X, sizeof A)
 16                           #define REP(i,l,u) for(int (i)=(int)(l);(i)<=(int)(u);++(i))
 17                           #define rep(i,l,u) for(int (i)=(int)(l);(i)>=(int)(u);--(i))
 18                           #define foreach(e,x) for(__typeof(x.begin()) e=x.begin();e!=x.end();++e)
 19                           typedef long long LL;
 20                           typedef unsigned long long ull;
 21                           typedef pair<long,long>  pll;
 22
 23
 24                           LL T,n;
 25                           const int mod=1e9+7;
 26                           const int maxn=10000;
 27                           int num[maxn+1];
 28 const int SIZE=1e5+300;//1e6;
 29                             bool isprime[SIZE];// filter[i]=true 表示i是素数.  筛选的范围是  0,1,2,... SIZE-1.  共SIZE个.    如果想筛0到7的素数,就把SIZE定为7+1;(因为总是多了个0)
 30                             void primefilte()
 31                             {
 32
 33                               for(int i=0;i<=1;i++) isprime[i]=false;
 34                               for (int i=2; i<=SIZE; i++)
 35                                {
 36                                 if(i & 1 || i==2) isprime[i] = true;
 37                                 else isprime[i] = false;
 38                               }
 39
 40                               for (int i=3; i<=(int)sqrt((long double)SIZE); i++)
 41                               {
 42                                 if (isprime[i])
 43                                 {
 44                                   int j = i*2;
 45                                   while (j<=SIZE)
 46                                   {
 47                                     if (isprime[j])
 48                                       isprime[j] = false;
 49                                     j+=i;
 50                                   }
 51                                 }
 52                               }
 53                                                                                           //for (int i=2; i<=SIZE-1; i++)
 54                                                                                            // if (isprime[i]) printf("%d ",i);
 55                             }
 56
 57                           vector<int> base;
 58                           void addint(int n,int p)
 59                           {
 60                               REP(i,0,base.size()-1)
 61                               {
 62                                   while(n%base[i]==0)
 63                                       {
 64                                           num[i]+=p;
 65                                           n/=base[i];
 66                                       }
 67                               }
 68                           }
 69                           void addf(int n,int p)
 70                           {
 71                               //rep(i,n,2)
 72                                //num[i]+=p;
 73                               REP(i,2,n)
 74                               addint(i,p);
 75                           }
 76                           int main()
 77                           {
 78                                freopen("in.txt","r",stdin);
 79                                //while(cin>>n)
 80
 81                                primefilte();
 82                                REP(i,2,10000)
 83                                if(isprime[i]) base.pb(i);
 84
 85                                int p,q,r,s;
 86                                while(cin>>p>>q>>r>>s)
 87                                {
 88                                  //REP(kase,1,T)  { }
 89                                  mem(num,0);
 90                                  addf(p,1);
 91                                  addf(s,1);
 92                                  addf(r-s,1);
 93                                  addf(p-q,-1);
 94                                  addf(q,-1);
 95                                  addf(r,-1);
 96                                  double ans=1;
 97                                  REP(i,0,base.size()-1)
 98                                   ans*=pow(base[i],num[i]);
 99                                  printf("%.5lf\n",ans);
100                                }
101                             return 0;
102                           }
103
104                          /*
105                             note    :  有一个地方:刚开始直接用的1 2 3 ... 10000作的基(写起来简单),出错了,
106                                         因为这样表示太浪费,损失了精度(几乎每次计算都是很小的数计算,误差增大),
107                                         于是希望稠密表示,减少误差,唯一分解定理(单次计算数字增大),使得误差降低.
108                             debug   :  代码除了模板其他的代码不要复制,不然易出错.应该重新写
109                             optimize:
110                           */ 
时间: 2024-11-01 10:05:44

uva 10375的相关文章

UVA 10375 Choose and divide(数论)

The binomial coefficient C(m,n) is defined as m! C(m,n) = -------- n!(m-n)! Given four natural numbers p, q, r, and s, compute the the result of dividing C(p,q) by C(r,s). The Input Input consists of a sequence of lines. Each line contains four non-n

uva 10375 唯一分解定理 筛法求素数【数论】

唯一分解理论的基本内容: 任意一个大于1的正整数都能表示成若干个质数的乘积,且表示的方法是唯一的.换句话说,一个数能被唯一地分解成质因数的乘积.因此这个定理又叫做唯一分解定理. 举个栗子:50=(2^1)*(5^2) 题目一般的思路就是要把素数表打出来,eg上面的例子 e={1,0,2,0,0......} 下面是两个题目,仅说说大致的思想: 题目一: E=(X1*X3*X4* ...*Xk)/X2   判断E是不是整数 如果把(X1*X3*X4* ...*Xk)分解成素数相乘,将X2也分解成素

【暑假】[数学]UVa 10375 Choose and divide

UVa 10375 Choose and divide 题目: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19601 思路: maxn=10000 如果计算maxn!再保存的话显然装不下. 但答案由阶乘的积或商组成,所以可以用唯一分解定理求解.大题思路就是把目前答案的质因子的指数用数组e保存,乘除都对e操作. 需要注意的是筛法求素数优化后的写法. 代码: 1 #include<iostream> 2 #include

UVA - 10375 - Choose and divide (组合数)

题目传送:UVA - 10375 思路:用double存答案,不过要注意是边乘边除,这样不会爆double,还有记得乘的时候要把int转换成double AC代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cmath> #include <queue> #include <stack> #

UVA 10375 Choose and divide(唯一分解定理)

这么大数的乘法.除法运算,肯定不能先全部乘起来,我的思路是计算出分子.分母上的每个数的个数(因为最大的数为10000,可以开一个数组记录个数). 利用了随机数方法终于知道错在哪了,中间如果出现连乘还是会溢出,这点没想到,以下是我的溢出代码: #include<stdio.h> #include<math.h> #include<iostream> #include<string.h> #include<stdlib.h> #include<

UVA 10375 选择与除法

一看四个整数的范围,<=10000  所以我们肯定不能直接打表求阶乘 利用唯一分解定理(任何一个大于1的正整数都能够被唯一地分解成质因子乘积) #include<iostream> #include<string> #include<string> #include<string.h> #include<stdio.h> #include<queue> #include<math.h> #include<vec

UVA 10375 Choose and divide

紫上给得比较奇怪,其实没有必要用唯一分解定理.我觉得这道题用唯一分解只是为了表示大数. 但是分解得到的幂,累乘的时候如果顺序很奇怪也可能溢出.其实直接边乘边除就好了.因为答案保证不会溢出, 设定一个精度范围,如果中间结果超过了精度范围就保存起来,最后sort一遍从两端同时乘就不会溢出了. /********************************************************* * --------------Tyrannosaurus--------- * * aut

UVa 10375 (唯一分解定理) Choose and divide

题意: 求组合数C(p, q) / C(r, s)结果保留5为小数. 分析: 先用筛法求出10000以内的质数,然后计算每个素数对应的指数,最后再根据指数计算答案. 1 #include <cstdio> 2 #include <cmath> 3 #include <cstring> 4 5 const int maxn = 10000; 6 int pri[maxn], cnt, e[maxn]; //e记录每个素数的质数 7 bool vis[maxn + 10];

UVA 10375 Choose and divide【唯一分解定理】

题意:求C(p,q)/C(r,s),4个数均小于10000,答案不大于10^8 思路:根据答案的范围猜测,不需要使用高精度.根据唯一分解定理,每一个数都可以分解成若干素数相乘.先求出10000以内的所有素数,用a数组表示唯一分解式中个素数的指数,求出每个分子部分的素因子,并且相应的素数的指数加一.分母则减一.最后求解唯一分解式的值. #include<stdio.h> #include<string.h> #include<math.h> const int N=1e4