传送门

文章目录

  • 题意:
  • 思路:

题意:

给你一个大轮盘,被分成了nnn个区域0,1,2,..,n−10,1,2,..,n-10,1,2,..,n−1,每个区域被转到的概率是ai∑j=0n−1aj\frac{a_i}{\sum_{j=0}^{n-1}a_j}∑j=0n−1​aj​ai​​,转到第iii个区域的时候得分是iii。现在你初始有x=0x=0x=0分,每次转动轮盘假设得到了yyy分,那么如果x⊕y≤xx\oplus y\le xx⊕y≤x的话,当前得分不会变化,否则将x=x⊕yx=x\oplus yx=x⊕y,当得分达到n−1n-1n−1的时候立即停止,问你转转盘轮数的期望。
2≤n≤2162\le n\le2^{16}2≤n≤216,且nnn为222的幂次。

思路:

以下我们约定:aia_iai​代表得分为iii的概率。
考虑期望dpdpdp,我们这里倒着来推,所以设f[i]f[i]f[i]表示当得分为iii的时候还需要进行的轮数期望是多少,很容易就可以得到n2n^2n2的一个转移方程:fi=∑j=0n−1[(i⊕j)>i](fi⊕j+1)∗aj+∑j=0n−1[(i⊕j≤i)](fi+1)∗ajf_i=\sum_{j=0}^{n-1}[(i\oplus j)>i](f_{i\oplus j}+1)*a_j+\sum_{j=0}^{n-1}[(i\oplus j\le i)](f_i+1)*a_jfi​=j=0∑n−1​[(i⊕j)>i](fi⊕j​+1)∗aj​+j=0∑n−1​[(i⊕j≤i)](fi​+1)∗aj​
考虑到方程两边都有f[i]f[i]f[i],我们进行移项:
fi=∑j=0n−1aj+∑j=0n−1[(i⊕j)>i]fi⊕j∗aj1−∑j=0n−1[(i⊕j≤i)]ajf_i=\frac{\sum_{j=0}^{n-1}a_j+\sum_{j=0}^{n-1}[(i\oplus j)>i]f_{i\oplus j}*a_j}{1-\sum_{j=0}^{n-1}[(i\oplus j\le i)]a_j}fi​=1−∑j=0n−1​[(i⊕j≤i)]aj​∑j=0n−1​aj​+∑j=0n−1​[(i⊕j)>i]fi⊕j​∗aj​​
这个式子一眼看去只能n2n^2n2求,可以发现瓶颈就在∑j=0n−1[(i⊕j)>i]fi⊕j∗aj\sum_{j=0}^{n-1}[(i\oplus j)>i]f_{i\oplus j}*a_j∑j=0n−1​[(i⊕j)>i]fi⊕j​∗aj​这个式子上,我们将其化简一下,设x=i,y=j,z=x⊕yx=i,y=j,z=x\oplus yx=i,y=j,z=x⊕y,f(x)=∑x⊕y=z,z>xf(z)a(y)f(x)=\sum_{x\oplus y=z,z>x}f(z)a(y)f(x)=∑x⊕y=z,z>x​f(z)a(y),看到f(x)f(x)f(x)的式子很像异或卷积,所以为了更直观,继续化简f(x)=∑z⊕y=x,z>xf(z)a(y)f(x)=\sum_{z\oplus y=x,z>x}f(z)a(y)f(x)=∑z⊕y=x,z>x​f(z)a(y)。
观察可知,那么去掉z>xz>xz>x的条件的话,这个就是一个异或卷积的裸式子了,考虑到对于iii只有>i>i>i的fff能对其有贡献,所以考虑cdqcdqcdq分治来计算这个式子,就可以去掉z>xz>xz>x这个条件了。在分治的过程中,只需要先递归计算右边的值,让后计算当前左区间的值,再递归左区间处理子问题即可。
但是问题还没有解决,a(y)a(y)a(y)怎么确定呢?在卷的过程中我们需要保证所有aaa都需要符合条件才可,不然会卷出来其他不合法的答案。考虑当前区间分成的两部分[l,mid],[mid+1,r][l,mid],[mid+1,r][l,mid],[mid+1,r]对应的二进制分别是[xxx000,xxx011],[xxx100,xxx111][xxx000,xxx011],[xxx100,xxx111][xxx000,xxx011],[xxx100,xxx111],发现了什么?我们计算左区间的时候,他们的aaa是那些部分呢?显然答案应该是aaa中下标在[100,111][100,111][100,111]的范围内的数,可以发现左区间[xxx000,xxx011][xxx000,xxx011][xxx000,xxx011]异或上区间内任何一个数都会准确的落在右区间的某个位置,且只有这些数能落在右区间。所以卷的时候让右区间的fff和上面的aaa对应区间卷起来即可。
递归到l=rl=rl=r的时候直接计算答案即可。

// Problem: Gambling Monster
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/11257/D
// Memory Limit: 524288 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)//#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")
//#pragma GCC optimize(2)
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<cctype>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<sstream>
#include<ctime>
#include<cstdlib>
#include<random>
#include<cassert>
#define X first
#define Y second
#define L (u<<1)
#define R (u<<1|1)
#define pb push_back
#define mk make_pair
#define Mid ((tr[u].l+tr[u].r)>>1)
#define Len(u) (tr[u].r-tr[u].l+1)
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define db puts("---")
using namespace std;//void rd_cre() { freopen("d://dp//data.txt","w",stdout); srand(time(NULL)); }
//void rd_ac() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//AC.txt","w",stdout); }
//void rd_wa() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//WA.txt","w",stdout); }typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;const int N=100010,mod=1e9+7,INF=0x3f3f3f3f;
const double eps=1e-6;int n;
int a[N],b[N],c;
LL f[N],iv2,u[N],all;LL qmi(LL a,LL b) {LL ans=1;  a%=mod; a+=mod; a%=mod;while(b) {if(b&1) ans=ans*a%mod;a=a*a%mod;b>>=1;}return ans%mod;
}int x[N], y[N];
void FWT_xor(int *a,int opt,int N)
{for(int i=1;i<N;i<<=1)for(int p=i<<1,j=0;j<N;j+=p)for(int k=0;k<i;++k){int X=a[j+k],Y=a[i+j+k];a[j+k]=(X+Y)%mod;a[i+j+k]=(X+mod-Y)%mod;if(opt==-1)a[j+k]=1ll*a[j+k]*iv2%mod,a[i+j+k]=1ll*a[i+j+k]*iv2%mod;}
}void cdq(int d,int l,int r,LL sa) {if(l==r) {f[l]+=all%mod; f[l]%=mod;(f[l]*=qmi(1-(all-sa)%mod,mod-2))%=mod;return;} int len=1<<d; LL sum=0;cdq(d-1,l+len,r,sa);for(int i=0;i<len;i++) {x[i]=a[i+len]; sum+=x[i]; sum%=mod;y[i]=f[i+l+len];}FWT_xor(x,1,len); FWT_xor(y,1,len);for(int i=0;i<len;i++) {x[i]=1ll*x[i]*y[i]%mod;}FWT_xor(x,-1,len);for(int i=0;i<len;i++) {(f[i+l]+=x[i])%=mod;  }cdq(d-1,l,l+len-1,(sa+sum)%mod);
}int main()
{//  ios::sync_with_stdio(false);
//  cin.tie(0);iv2=qmi(2,mod-2);int _; scanf("%d",&_);while(_--) {scanf("%d",&n); LL sum=0;memset(f,0,sizeof(f));for(int i=0;i<n;i++) scanf("%d",&a[i]),sum+=a[i];sum=qmi(sum,mod-2);  all=0;for(int i=0;i<n;i++) a[i]=a[i]*sum%mod,all+=a[i],all%=mod;for(int i=16;i>=0;i--) {if((1<<i)==n) {cdq(i-1,0,n-1,0);break;}}printf("%lld\n",f[0]%mod);}return 0;
}
/*
200000005
3
3
0*/

2021牛客暑期多校训练营6 :D Gambling Monster 期望dp + fwt + cdq分治相关推荐

  1. 2021牛客暑期多校训练营4 B - Sample Game 期望dp\生成函数

    传送门 文章目录 题意: 思路: 题意: 给你一个生成器,每次生成1−n1-n1−n其中的某个数的概率为pip_ipi​,生成的规则如下: (1)(1)(1)随机生成一个数加入集合. (2)(2)(2 ...

  2. 2021牛客暑期多校训练营1 I-Increasing Subsequence(期望dp+优化)

    I-Increasing Subsequence fi,j,0/1f_{i,j,0/1}fi,j,0/1​表示上一轮第一个人选了iii,第二个人选了jjj,并且当前是第1/2个人选择的概率. 转移考虑 ...

  3. 2021牛客暑期多校训练营8 F-Robots(bitset优化dp)

    F-Robots 第一种第二种机器人直接O(n)O(n)O(n)判断即可. 第三种机器人暴力dp,用bitset优化. bitset<250005> b[i][j] 表示从(i,j)(i, ...

  4. 2021牛客暑期多校训练营5 E-Eert Esiwtib(树形dp+位运算)

    E-Eert Esiwtib 位运算考虑贡献时分0/1按位模拟考虑 fu,0/1/2f_{u,0/1/2}fu,0/1/2​表示子树u中点(包括u)到u所有路径的或/与/异或值. 转移的时候我们要考虑 ...

  5. 2021牛客暑期多校训练营4 B-Sample Game(概率DP)

    B-Sample Game ding_ning123大佬题解 注:上述题解图片来自ding_ning123大佬题解 Code #include<bits/stdc++.h> using n ...

  6. 2021牛客暑期多校训练营9

    2021牛客暑期多校训练营9 题号 题目 知识点 A A Math Challenge B Best Subgraph C Cells D Divide-and-conquer on Tree E E ...

  7. 2021牛客暑期多校训练营5

    2021牛客暑期多校训练营5 题号 题目 知识点 A Away from College B Boxes 概率 C Cheating and Stealing D Double Strings 线性d ...

  8. 2021牛客暑期多校训练营4

    2021牛客暑期多校训练营4 题号 题目 知识点 A Course B Sample Game C LCS D Rebuild Tree E Tree Xor 思维+线段树 F Just a joke ...

  9. 2021牛客暑期多校训练营3

    2021牛客暑期多校训练营3 题号 题目 知识点 A Guess and lies B Black and white C Minimum grid 二分图匹配 D Count E Math 数论+打 ...

最新文章

  1. DTCMS,手机网站访问跳转到DTCMS官网解决方法
  2. JVM PrintGCDetails打印GC细节
  3. php yaf 教程,Yaf教程2:入门使用
  4. 【C++学习笔记五】模板
  5. redux引用多个中间件_如何轻松创建您的第一个Redux中间件
  6. 的一致性哈希_五分钟看懂一致性哈希算法
  7. Python nonlocal 与 global 关键字解析
  8. C/C++ Bug记录
  9. 6.1行为型模式--模板方法模式
  10. arXiv上引用文章在bibtex下的引用格式
  11. java retainAll
  12. 微信小程序原生自定义组件布局问题
  13. Winkey(Windows徽标键)
  14. 华为研究院高级研究员几年心得终得趣谈网络协议文档,附资深架构师讲解
  15. 电脑重装系统UEFI启动如何设置
  16. 用matlab绘制抛物线y的x平方,利用matlab绘制多重x/y曲线
  17. 智慧旅游建设智能化景区管理系统方案
  18. 经典C语言编程100例——题目+答案代码(21-30)
  19. Android Studio开发APP
  20. 23-Vue和Element基础

热门文章

  1. 除了PS,原来这个也可以轻松实现图像处理!
  2. 一顿家庭火锅让本不富裕的家庭雪上加霜......
  3. mySQL微信小程序的div_做一个微信小程序的完整流程
  4. 10以内的分解与组成怎么教_狗狗酷炫的飞盘游戏怎么玩?分解步骤教你快速学会...
  5. 怎样让电脑速度变快_硬盘在电脑中起什么作用?
  6. android 更改edittext内容,Android如何实时更改edittext的内容
  7. dw自动滚动图片_3分钟搞定图片懒加载
  8. html答题赚钱源码,WTS在线答题系统 v1.0.0
  9. 计算机的科学原理是什么,人工智能的工作原理是什么?
  10. linux备份文件到ftp上,Linux服务器下用FTP上传下载备份文件