uva - 10833 Supermean(二项式系数,对指数)

模拟发现,每个元素求和时,元素的系数是二项式系数,于是ans=sum(C(n-1,i)*a[i]/2^(n-1)),但是n太大,直接求会溢出,其实double的范围还是挺大的,所以可以将组合数转化成对数:

e^(lnC(n-1, k)*A[k]/(2^n-1) )  ==>  e^( ln C(n-1,k) + ln A[k] - (n-1)*ln2 );

又直接利用公式求二项式系数:C(n, k+1)/C(n, k) = (n-k)/(k+1);

而且对数还有递推求法:

logC(n,k+1)=logC(n,k)+log(n-k)-log(k+1)

代码:

 1 #include <iostream>
 2 #include <sstream>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <cmath>
 6 #include <string>
 7 #include <vector>
 8 #include <set>
 9 #include <cctype>
10 #include <algorithm>
11 #include <cmath>
12 #include <deque>
13 #include <queue>
14 #include <map>
15 #include <stack>
16 #include <list>
17 #include <iomanip>
18
19 using namespace std;
20
21 #define INF 0xffffff7
22 #define maxn 50010
23 const double tmp = log(2.0);
24 double data[maxn];
25 int main()
26 {
27     int T;
28     scanf("%d", &T);
29     for(int kase = 1; kase <= T; kase++)
30     {
31         int n;
32         scanf("%d", &n);
33         double ans = 0.0, c = 0.0;
34         for(int i = 0; i < n; i++)
35         {
36             scanf("%lf", &data[i]);
37             if(data[i] > 0) ans += exp(log(data[i]) - (n-1)*log(2.0) + c);
38             else if(data[i] < 0) ans -= exp(log(-data[i]) - (n-1)*log(2.0) + c);
39             //cout << ans << endl;
40             c += log((double)n-i-1)-log((double)i+1);
41         }
42         printf("Case #%d: %.3lf\n", kase, ans);
43     }
44     return 0;
45 }
时间: 2024-11-08 07:16:17

uva - 10833 Supermean(二项式系数,对指数)的相关文章

UVA - 10883 Supermean

Description Problem F Supermean Time Limit: 2 second "I have not failed. I've just found 10,000 ways that won't work." Thomas Edison Do you know how to compute the mean (or average) of n numbers? Well, that's not good enough for me. I want the s

UVA 10883 - Supermean(组合数学+数值优化)

题目链接:10883 - Supermean 题意:求超级平均数,就是相邻两个算一个平均数,直到剩下一个数,求数值. 思路:画图很容易推断出公式.就拿最后一组样例来说 1     2      3      4      5 1.5  2.5   3.5   4.5 2       3      4 2.5   3.5 3 观察可以发现都是从顶到底,看又几条路线,就有几次,然后最后每个数字在除上相应次数的2,那几条路线就是C(n - 1, [0 - n - 1])的组合数. 所以ans = su

UVA 10883 Supermean 上下取对数防溢出

题目链接:点击打开链接 溢出了半天,觉累不爱 #include<math.h> #include<iostream> #include<stdio.h> using namespace std; #define ll int int main(){ ll Cas= 1, T; cin>>T; while(T--){ ll n; cin>>n; double sum = 0, a; double hehe = 0; for(ll i = 0; i

uva 10883 - Supermean(组合数学+数值优化)

题目链接:uva 10883 - Supermean 题目大意:给出n个数,每相邻两个数求平均数,将得到n-1个数,这n-1个数每相邻的两个数求平均值,将得到n-2个数.一次类推,求最后得到的那个数的值. 解题思路:类似与杨辉三角,第i个数起始被加了C(n?1i?1)次.总共有2n?1个数相加.但是因为n有50000,250000根本存不下,所以借助log函数. 例: 中间的2可以通过蓝色和红色两条路径影响最后的答案. #include <cstdio> #include <cstrin

UVa 10883 超级平均数(二项式系数+对数计算)

https://vjudge.net/problem/UVA-10883 题意: 给出n个数,每相邻两个数求平均数,依次类推,最后得到1个数,求该数. 思路: 演算一下可以发现最后各个数的系数就是二项式系数. 但是n太大,直接计算会溢出. 所以,这里要用对数计算.(cmath中的log默认以e为底) 1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio>

UVA 10692 Huge Mods(指数循环节)

指数循环节,由于a ^x = a ^(x % m + phi(m)) (mod m)仅在x >= phi(m)时成立,故应注意要判断 //by:Gavin http://www.cnblogs.com/IMGavin/ //指数循环节 递归处理 #include<cstdio> #include<iostream> #include<cstdlib> #include<cstring> #include<string> #include&l

Uva 10629 Huge Mods (指数循环节)

题意:求 a1?a2?a3?. . .?aN mod m 思路:利用 和递归求解 代码: #include <iostream> #include <string.h> #include <stdio.h> using namespace std; const int N=15; typedef long long ll; int MOD; int A[N],k; int phi(int n) { int rea = n; for(int i=2; i*i<=n;

UVA 10050 Hartals (罢工指数,暴力枚举。)

Hartals A social research organization has determined a simple set of parameters to simulate the behavior of the political parties of our country. One of the parameters is a positive integerh (called the hartal parameter) that denotes the average num

UVA 11752 超级幂

UVA 11752 超级幂 Z - The Super Powers Time Limit:1000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice UVA 11752 Description 题意:定义一个数为超级幂,当这个数能表示成至少两个不同数字的幂时.如16=2^4,16=4^2.输出1~2^64-1范围内的超级幂. 思路:显然一个数能称为超级幂,这个数肯定是一个数的合数幂,即a^