BZOJ4675 点对游戏
来源:互联网 发布:温柔强大动漫男主 知乎 编辑:程序博客网 时间:2024/06/01 21:38
根据期望的线性性(orz xuruifan,我们一定要叫线性性,不能叫可加性),期望幸运点对数等于每个幸运点对被选中的概率之和
由于每个点都是等价的,所以每个点对也是等价的,所以我们只需要计算1个点对被选中的概率,乘以点对数再乘以2(因为是有序的)即可
一个点对被选中的概率等于他在每次操作下被选中的概率之和
假设这个点对是(x,y)
对于一个人,第i次操作一定会选择一个点,x被选中的概率是1/n
如果这次选择了x,在之前的i-1次操作中,一定不会选择x,所以每次会在n-1个点中随机选一个没被选中的,所以y被选中的概率是i-1/n-1
所以一个人的第i次操作对答案的贡献是(1/n)*(i-1/n-1)*幸运点对数×2
至于如何求幸运点对数,这是点分治的经典问题,可以在O(mn log n)时间内求出
其实我们也可以用类似BZOJ4543 POI2014 HOTEL加强版的方法来优化n^2的DP,在O(nm)的时间,O(n)的空间内求出
我写的是优化DP,因为我做这道题的时候脑抽,忘了这是点分治经典问题了-_-
#include<iostream>#include<cstdlib>#include<cstdio>#include<cstring>#include<cmath>#include<ctime>#include<algorithm>#include<iomanip>#include<vector>#include<stack>#include<queue>#include<map>#include<set>#include<bitset>using namespace std;#define MAXN 50010#define MAXM 1010#define ll long long#define INF 1000000000#define MOD 1000000007#define eps 1e-8struct vec{ int to; int fro;};vec mp[MAXN*2];int tai[MAXN],cnt;int g[MAXN];int F[MAXN*8];int *f[MAXN];int *hat=F+2;int d[MAXN];int n,m;int l[MAXN];int son[MAXN];double cs[5],ans[5];int lw[MAXN];int dep[MAXN];inline void be(int x,int y){ mp[++cnt].to=y; mp[cnt].fro=tai[x]; tai[x]=cnt;}inline void bde(int x,int y){ be(x,y); be(y,x);}void pre(int x,int F){ int i,y; lw[x]=x; dep[x]=dep[F]+1; for(i=tai[x];i;i=mp[i].fro){ y=mp[i].to; if(y==F){ continue ; } pre(y,x); if(d[y]+1>d[x]){ son[x]=y; lw[x]=lw[y]; d[x]=d[y]+1; } } for(i=tai[x];i;i=mp[i].fro){ y=mp[i].to; if(y!=son[x]&&y!=F){ hat+=dep[lw[y]]-dep[y]+2; f[lw[y]]=hat; hat+=5; } } if(x==1){ hat+=dep[lw[x]]-dep[x]+2; f[lw[x]]=hat; }}void dfs(int x,int F){ int i,j,k,y; for(i=tai[x];i;i=mp[i].fro){ y=mp[i].to; if(y==F){ continue ; } dfs(y,x); if(y==son[x]){ f[x]=f[y]-1; g[x]+=g[y]; for(j=1;j<=m;j++){ if(l[j]-1<=d[y]){ g[x]+=f[y][l[j]-1]; } } } } f[x][0]=1; for(i=tai[x];i;i=mp[i].fro){ y=mp[i].to; if(y==F||y==son[x]){ continue ; } g[x]+=g[y]; for(j=0;j<=d[y];j++){ for(k=1;k<=m;k++){ if(j<l[k]&&l[k]-j-1<=d[x]){ g[x]+=f[y][j]*f[x][l[k]-j-1]; } } } for(j=0;j<=d[y];j++){ f[x][j+1]+=f[y][j]; } }}int main(){ int i,x,y; scanf("%d%d",&n,&m); for(i=1;i<=m;i++){ scanf("%d",&l[i]); } for(i=1;i<n;i++){ scanf("%d%d",&x,&y); bde(x,y); } pre(1,0); dfs(1,0); for(i=1;i<=n;i++){ ans[(i-1)%3+1]+=1.0/n*cs[(i-1)%3+1]*g[1]*2; cs[(i-1)%3+1]+=1.0/(n-1); } for(i=1;i<=3;i++){ printf("%.2lf\n",ans[i]); } return 0;} /*6 21 31 22 31 41 52 6 */
0 0
- BZOJ4675 点对游戏
- 游戏策划:对新人的几点建议
- 对踵点对
- 24点游戏代码
- 24点游戏
- 24点扑克牌游戏
- 21点游戏
- 24点游戏
- 24点游戏
- 《24点游戏》
- 24点游戏
- 24点游戏
- 24点游戏
- 24点游戏
- 24点游戏
- 24点游戏
- 黄金点游戏
- 24点游戏
- POJ.2559[leetcode.84]直方图最大矩形及二维情况
- 压缩vector的技巧
- 试水多线程-同步方法
- 计划
- java旅行第二站--JavaSE第八天--用计时器将内容写入文件
- BZOJ4675 点对游戏
- 二分_E
- hdu 5818 Joint Stacks 2016 Multi-University 7
- 侧滑菜单 residemenu第三方的使用
- TextUtils.isEmpty()的意思
- MyEclipse201添加SQL Server sqljdbc的maven依赖 (Missing artifact com.microsoft.sqlserver:sqljdbc4:jar:4.0)
- 从事移动开发大概一年的时间,担心自己变成框架化程序员,应该如何做能提高自己的能力?
- com 引用计数探索
- Python 教程之面向对象