【题目大意】

给出$n$个三维向量,设当前向量长度为$L$,每次沿着向量等概率走$[0,L]$个长度。一个球每秒半径增加1个长度,直到覆盖位置,每秒耗能为球体积,求总耗能的期望。

设最后半径为R,那么求得就是$ \int_0^R \frac{4}{3}\pi x^3\, dx.$的期望。

$1 \leq n \leq 3000$

【题解】

也就是求$E(\frac{\pi}{3}R^4)$,问题在于怎么求$E(R^4)$。

先提供一种错误做法及其实现:

我们设向量为$\{p_n\}$,设$x_i$是$(0,1)$等概率随机的。

那么相当于求$E( (\sum_{i=1}^n p_ix_i)^4 )$。

拆出一个数,相当于

$E((\sum_{i=1}^{n-1} p_ix_i + p_nx_n)^4)$

二项式展开,得

$E( (\sum_{i=1}^{n-1}p_ix_i)^4 + 4(\sum_{i=1}^{n-1}p_ix_i)^3(p_nx_n) + 6(\sum_{i=1}^{n-1}p_ix_i)^2(p_nx_n)^2+4(\sum_{i=1}^{n-1}p_ix_i)(p_nx_n)^3 + (p_nx_n)^4)$

所以我们只要维护$p_ix_i$的1~4次方的期望就行了吗?

讲道理是的啊,但是这种做法是错的,只能在所有向量同向的时候是对的。

为什么呢?因为考虑期望中有向量和向量数乘的一项,比如$4(\sum_{i=1}^{n-1}p_ix_i)(p_nx_n)^3$,这是不支持结合律的!!!

所以。。是错的qwq

======================分割线======================

我们接下来讲正确的做法

我们考虑把向量分成三个坐标表示$(a_i,b_i,c_i)$。

求$E(R^4)$还可以看做$E( ((\sum_{i=1}^{n} a_ix_i)^2 + (\sum_{i=1}^{n} b_ix_i)^2 + (\sum_{i=1}^{n} c_ix_i)^2) ^2)$

这样好像正常多了,至少没有向量了。

设当前做到k,当前的$p = \sum_{i=1}^k a_ix_i$,$q = \sum_{i=1}^k b_ix_i$,$r = \sum_{i=1}^k c_ix_i$。

那么也就是求$E( (p^2+q^2+r^2)^2 ) = E(p^4+q^4+r^4+2p^2q^2+2p^2r^2+2q^2r^2)$

设f[x,i,j,k]表示加到第x个向量,$p^i * q^j * r^k$的期望。

那么根据期望的线性性,答案就是f[n,4,0,0]+f[n,0,4,0]+f[n,0,0,4]+2 * (f[n,0,2,2]+f[n,2,0,2]+f[n,2,2,0])

考虑转移,每次加入一个向量,我们试着把其中一项加入当前的$a_ix_i,b_ix_i,c_ix_i$(记为$p',q',r'$)。

$E((p+p')^2(q+q')^2) = E((p^2+2pp'+p'^2)(q^2+2qq'+q'^2)) = E(p^2q^2+ 2p^2qq' + p^2q'^2+2pq^2p' + 4pqp'q' + 2pp'q'^2 + q^2p'^2 + 2qp'^2q' + p'^2q'^2)$

可能已经发现了转移方式了

f[x,i,j,k] = f[x-1, i-A, j-B, k-C] * E(A, B, C) * C(i, A) * C(j, B) * C(k, C)

E(a,b,c)表示$p'^A * q'^B * r'^C$的期望,根据定义显然就是求$E(a_i^Ab_i^Bc_i^Cx_i^{A+B+C})$的期望。

这里$x_i$是$(0,1)$的变量,所以$E(x_i^p) = 1/(p+1)$。由于$x_i$和前面几个x都是互相独立的,所以这时候$E(AB) = E(A)E(B)$.

$a_i^Ab_i^Bc_i^C$都是常数,所以最后答案是$a_i^Ab_i^Bc_i^C / (A+B+C+1)$

然后就可以转移啦。。

复杂度O(n * 常数)

# include <math.h>
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm> using namespace std; typedef long long ll;
typedef unsigned long long ull;
typedef long double ld; const int M = 3e3 + ;
const int mod = 1e9 + ;
const ld pi = acos(-1.0); int C[][], n;
ld f[][][][], E[][][];
ld a[M], b[M], c[M], sa[M], sb[M], sc[M]; // E(R^4) = E( ((∑a_i*x_i)^2 + (∑b_i*x_i)^2 + (∑c_i*x_i)^2)^2 )
// p = ∑a_i*x_i, q = ∑b_i*x_i, r = ∑c_i*x_i
// E(R^4) = E( p^4 + q^4 + r^4 + 2p^2 q^2 + 2p^2 r^2 + 2q^2 r^2 ) // p = p + a_nx_n, q = q + b_nx_n, r = r + c_nx_n // E((a_nx_n) ^ A * (b_nx_n) ^ B * (c_nx_n) ^ C) /*
e.g.
(p+p')^2(q+q'^2)
= (p^2+2pp'+p'^2)(q^2+2qq'+q'^2)
= p^2q^2 + 2p^2q * q' + p^2q'^2 + ...
*/ int main() {
// freopen("find.in", "r", stdin);
// freopen("find.out", "w", stdout);
C[][] = ;
for (int i=; i<=; ++i) {
C[i][] = ;
for (int j=; j<=i; ++j) C[i][j] = C[i-][j] + C[i-][j-];
}
while(cin >> n) {
if(!n) continue;
memset(f, , sizeof f);
int cur = , pre = ;
f[pre][][][] = ;
double Alpha, Beta, L;
for (int i=; i<=n; ++i) {
scanf("%lf%lf%lf", &Alpha, &Beta, &L);
a[i] = L * cos(Beta) * cos(Alpha), b[i] = L * cos(Beta) * sin(Alpha), c[i] = L * sin(Beta);
}
for (int i=; i<=n; ++i) {
sa[] = sb[] = sc[] = ;
for (int j=; j<=; ++j) {
sa[j] = sa[j-] * a[i];
sb[j] = sb[j-] * b[i];
sc[j] = sc[j-] * c[i];
}
for (int i=; i<=; ++i)
for (int j=; i+j<=; ++j)
for (int k=; i+j+k<=; ++k)
E[i][j][k] = sa[i] * sb[j] * sc[k] / (i+j+k+);
for (int i=; i<=; ++i)
for (int j=; i+j<=; ++j)
for (int k=; i+j+k<=; ++k) {
f[cur][i][j][k] = ;
for (int x=; x<=i; ++x)
for (int y=; y<=j; ++y)
for (int z=; z<=k; ++z)
f[cur][i][j][k] += f[pre][i-x][j-y][k-z] * E[x][y][z] * C[i][x] * C[j][y] * C[k][z];
}
swap(pre, cur);
}
ld ans = f[pre][][][] + f[pre][][][] + f[pre][][][] + 2.0 * (f[pre][][][] + f[pre][][][] + f[pre][][][]);
ans = ans / 3.0 * pi;
printf("%.9lf\n", (double)ans);
}
return ;
}

下面这份是只能过共线的代码:

# include <math.h>
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm> using namespace std; typedef long long ll;
typedef unsigned long long ull;
typedef long double ld; const int M = 3e3 + , N = 1e5 + ;
const int mod = 1e9 + ;
const double pi = acos(-1.0); int n; struct vec {
bool f;
double a, b, c;
vec() {}
inline void set(bool _f, double _a, double _b = 0.0, double _c = 0.0) {
f = _f;
a = _a, b = _b, c = _c;
}
friend vec operator + (vec a, vec b) {
vec ret;
if(a.f && b.f) ret.set(, a.a+b.a, a.b+b.b, a.c+b.c);
else ret.set(, a.a+b.a);
return ret;
}
friend vec operator * (vec a, vec b) {
vec ret;
if(a.f && b.f) ret.set(, a.a * b.a + a.b * b.b + a.c * b.c);
if(a.f && !b.f) ret.set(, a.a * b.a, a.b * b.a, a.c * b.a);
if(!a.f && b.f) ret.set(, a.a * b.a, a.a * b.b, a.a * b.c);
if(!a.f && !b.f) ret.set(, a.a * b.a);
return ret;
}
friend vec operator * (vec a, double b) {
vec ret;
if(a.f) ret.set(, a.a*b, a.b*b, a.c*b);
else ret.set(, a.a*b);
return ret;
}
friend vec operator / (vec a, double b) {
vec ret;
if(a.f) ret.set(, a.a/b, a.b/b, a.c/b);
else ret.set(, a.a/b);
return ret;
}
inline void out() {
if(f) printf("%lf, %lf, %lf\n", a, b, c);
else printf("%lf\n", a);
}
}p[M][], a[M], f[M][]; int main() {
freopen("find.in", "r", stdin);
freopen("find.out", "w", stdout);
while(cin >> n) {
double Alpha, Beta, L;
if(n == ) break;
for (int i=; i<=n; ++i) {
scanf("%lf%lf%lf", &Alpha, &Beta, &L);
a[i].set(, L * cos(Beta) * cos(Alpha), L * cos(Beta) * sin(Alpha), L * sin(Beta));
p[i][] = a[i] / 2.0;
p[i][] = (a[i] * a[i]) / 3.0;
p[i][] = (a[i] * a[i] * a[i]) / 4.0;
p[i][] = (a[i] * a[i] * a[i] * a[i]) / 5.0;
// cout << "i = " << i << endl;
// p[i][1].out();
// p[i][2].out();
// p[i][3].out();
// p[i][4].out();
// cout << endl;
}
/*
ans = 1/3 * pi * E(r^4) E((∑p[i]x[i])^4)
= E((∑p[i]x[i] + p[n]x[n]) ^ 4)
= E((∑p[i]x[i]) ^ 4) + 3E((∑p[i]x[i])^3)E(p[n]x[n]) + 6E((∑p[i]x[i])^2)E((p[n]x[n])^2) + 3E(∑p[i]x[i]) E((p[n]x[n])^3) + E((p[n]x[n])^4) E( (p[i]x[i])^3 )
= */
f[][] = p[][], f[][] = p[][], f[][] = p[][], f[][] = p[][];
for (int i=; i<=n; ++i) {
f[i][] = f[i-][] + p[i][];
f[i][] = f[i-][] + (f[i-][] * p[i][]) * + p[i][];
f[i][] = f[i-][] + (f[i-][] * p[i][]) * + (f[i-][] * p[i][]) * + p[i][];
f[i][] = f[i-][] + (f[i-][] * p[i][]) * + (f[i-][] * p[i][]) * + (f[i-][] * p[i][]) * + p[i][];
} double ans = f[n][].a * pi / 3.0;
printf("%.10lf\n", ans);
} return ;
}

「6月雅礼集训 2017 Day4」寻找天哥的更多相关文章

  1. 「6月雅礼集训 2017 Day4」qyh(bzoj2687 交与并)

    原题传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2687 [题目大意] 给出若干区间,求一个区间的大于等于2的子集,使得 |区间并| 和 | ...

  2. 「6月雅礼集训 2017 Day4」暴力大神hxx

    [题目大意] 给出一个n重循环,每重循环有范围$[l, r]$,其中$l$,$r$可能是之前的变量,也可能是常数.求循环最底层被执行了多少次. 其中,保证每个循环的$l$,$r$最多有一个是之前的变量 ...

  3. 「6月雅礼集训 2017 Day10」quote

    [题目大意] 一个合法的引号序列是空串:如果引号序列合法,那么在两边加上同一个引号也合法:或是把两个合法的引号序列拼起来也是合法的. 求长度为$n$,字符集大小为$k$的合法引号序列的个数.多组数据. ...

  4. 「6月雅礼集训 2017 Day11」delight

    [题目大意] 有$n$天,每天能吃饭.睡觉.什么事也不干 每天吃饭的愉悦值为$e_i$,睡觉的愉悦值为$s_i$,什么都不干愉悦值为0. 要求每连续$k$天都要有至少$E$天吃饭,$S$天睡觉. 求最 ...

  5. 「6月雅礼集训 2017 Day11」jump

    [题目大意] 有$n$个位置,每个位置有一个数$x_i$,代表从$i$经过1步可以到达的点在$[\max(1, i-x_i), \min(i+x_i, n)]$中. 定义$(i,j)$的距离表示从$i ...

  6. 「6月雅礼集训 2017 Day11」tree

    [题目大意] 给出一棵带权树,有两类点,一类黑点,一类白点. 求切断黑点和白点间路径的最小代价. $n \leq 10^5$ [题解] 直接最小割能过..但是树形dp明显更好写 设$f_{x,0/1/ ...

  7. 「6月雅礼集训 2017 Day10」perm(CodeForces 698F)

    [题目大意] 给出一个$n$个数的序列$\{a_n\}$,其中有些地方的数为0,要求你把这个序列填成一个1到$n$的排列,使得: $(a_i, a_j) = 1$,当且仅当$(i, j) = 1$.多 ...

  8. 「6月雅礼集训 2017 Day8」route

    [题目大意] 给出平面上$n$个点,求一条连接$n$个点的不相交的路径,使得转换的方向符合所给长度为$n-2$的字符串. $n \leq 5000$ [题解] 考虑取凸包上一点,然后如果下一个是‘R' ...

  9. 「6月雅礼集训 2017 Day8」gcd

    [题目大意] 定义times(a, b)表示用辗转相除计算a和b的最大公约数所需步骤. 那么有: 1. times(a, b) = times(b, a) 2. times(a, 0) = 0 3. ...

随机推荐

  1. Android - TabHost 选项卡功能用法详解

    TabHost效果图 : 源码下载地址 : http://download.csdn.net/detail/han1202012/6845105        . 作者 :万境绝尘  转载请注明出处  ...

  2. python 项目配置虚拟环境

    # Windows 环境1, 安装 Visual C++ 2015 Build Tools, 依赖.Net Framework 4.6, 安装包位置 ./tools/windows/visualcpp ...

  3. 求gcd(最大公因数),lcm(最小公倍数)模板

    gcd(最大公因数),lcm(最小公倍数) #include<iostream> using namespace std; int gcd(int a,int b)//辗转相除法(欧几里德 ...

  4. python学习第一天-语法学习

    1.python简介 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,Guido开始写能够解释Python语言语法的解释器.Python这个名字,来自 ...

  5. 对alpha发布的总结技术随笔

    对于今天的alpha发布,首先需要自我检讨,因为我们组没有展示作品.主要的原因还是我们投入的时间不足.我们的项目是约跑App,首先选择做安卓平台的东西,我们大家都需要熟悉新的开发软件Android S ...

  6. Agile.Net 组件式开发平台 - 驱动开发示例

    首先讲一下概念,此驱动非彼驱动.在Agle.Net中我们将组件规划成两种类型,一种是基于业务的窗体组件,一种是提供扩展功能的驱动组件. 打个比方例如一般系统中需要提供身份证读卡功能,然而市面上有很多种 ...

  7. 关键系统的JVM参数推荐

    1. 性能篇 1.1 建议的性能参数 1. 取消偏向锁: -XX:-UseBiasedLocking JDK1.6开始默认打开的偏向锁,会尝试把锁赋给第一个访问它的线程,取消同步块上的synchron ...

  8. 第29天:js-数组添加删除、数组和字符串相互转换

    一.添加数组var arr=[1,3,5];arr.push(7,9);//添加7和9到数组arr后面,得到[1,3,5,7,9]1.push();可向数组末尾添加一个或多个元素,并返回新的长度.2. ...

  9. 客户端 new socket时候 就像服务端发起连接了

    客户端 new socket时候  就像服务端发起连接了

  10. CentOS 服务ftp(vsftpd)

    1.检查是否已经安装vsftpd yum list installed | grep vsftpd 2.安装vsftpd yum install -y vsftpd 3.检查vsftpd system ...