题目链接:点击查看

题目大意:有一个转盘,每次转动得到 0∼n−10\sim n−10∼n−1(nnn 是 2 的幂)的概率分别给出。最开始你有一个数 x=0x=0x=0,每次转动转盘得到一个数 yyy,如果 x⊕y>xx\oplus y>xx⊕y>x,就令 x=x⊕yx=x\oplus yx=x⊕y,否则 xxx 不变。求使 x=n−1x=n-1x=n−1,期望转动转盘的次数。

题目分析:

求期望,考虑倒着的概率 dpdpdp

设 P[i]P[i]P[i] 为转到 iii 的概率,设 E[i]E[i]E[i] 代表当前数字为 iii,到达 n−1n-1n−1 的期望步数,显然 E[n−1]=0E[n-1]=0E[n−1]=0,答案是 E[0]E[0]E[0]

设 S[x]S[x]S[x] 代表转动一次转盘后 xxx 发生变化的概率(即变大)的概率,不难得到 S[x]=∑x⊕y>xP[y]S[x]=\sum\limits_{x\oplus y>x}P[y]S[x]=x⊕y>x∑​P[y]

那么 EEE 的方程分成两个部分也不难写出:E[x]=(E[x]+1)∗(1−S[x])+∑x⊕y=zx<z(E[z]+1)∗P[y]E[x]=(E[x]+1)*(1-S[x])+\sum\limits_{\overset{x<z}{x\oplus y=z}}(E[z]+1)*P[y]E[x]=(E[x]+1)∗(1−S[x])+x⊕y=zx<z​∑​(E[z]+1)∗P[y]

发现左右两侧都有 E[x]E[x]E[x],所以移一下项得到:
E[x]=(1−S[x])+∑x⊕y=zx<z(E[z]+1)∗P[y]S[x]E[x]=\frac{(1-S[x])+\sum\limits_{\overset{x<z}{x\oplus y=z}}(E[z]+1)*P[y]}{S[x]}E[x]=S[x](1−S[x])+x⊕y=zx<z​∑​(E[z]+1)∗P[y]​

对于 S[x]S[x]S[x],我们发现只需要找到 yyy 在二进制下最高位的 111,判断一下在 xxx 在二进制下是否为 000 就可以确定是否存在贡献,这个可以 O(nlogn)O(nlogn)O(nlogn) 预处理出来

对于 ∑x⊕y=zx<z(E[z]+1)∗P[y]\sum\limits_{\overset{x<z}{x\oplus y=z}}(E[z]+1)*P[y]x⊕y=zx<z​∑​(E[z]+1)∗P[y],不难发现是异或卷积的形式,又因为期望 dpdpdp 是倒着推的,所以后面的答案会对前面的答案具有贡献,这个可以用 cdqcdqcdq 分治套 FWTFWTFWT 来解决

需要注意的是,在分治的过程中后面的答案会影响前面的答案,所以我们需要先递归右子区间,然后再递归左子区间

最后就是如何确定公式中 yyy 的取值范围呢,如果每次都是取 0∼n−10\sim n-10∼n−1 的话肯定不行,通过分析不难发现,每次拆出来的左右区间形如:
[xxx0000]∼[xxx0111]+[xxx1000]∼[xxx1111][xxx0000]\sim[xxx0111]+[xxx1000]\sim[xxx1111][xxx0000]∼[xxx0111]+[xxx1000]∼[xxx1111]

我们上述式子中的 xxx 需要在左区间中取,zzz 需要在右区间中取,而 yyy 只需要满足 y=x⊕zy=x\oplus zy=x⊕z 即可,将上面的两段区间进行异或可以得到 y∈[1000,1111]y\in[1000,1111]y∈[1000,1111],这个每次通过位运算求解即可,不难发现 yyy 和 zzz 的区间刚好是等阶的

代码:

// 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(2)
// #pragma GCC optimize("Ofast","inline","-ffast-math")
// #pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
#include<list>
#include<unordered_map>
#define lowbit(x) (x&-x)
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
template<typename T>
inline void read(T &x)
{T f=1;x=0;char ch=getchar();while(0==isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(0!=isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();x*=f;
}
template<typename T>
inline void write(T x)
{if(x<0){x=~(x-1);putchar('-');}if(x>9)write(x/10);putchar(x%10+'0');
}
const int inf=0x3f3f3f3f;
const int N=1e6+100;
const int mod=1e9+7;
int n;
LL P[N],S[N],invS[N],E[N],tmp[20],a[N],b[N];
LL q_pow(LL a,LL b) {LL ans=1;while(b) {if(b&1) {ans=ans*a%mod;}a=a*a%mod;b>>=1;}return ans;
}
LL inv(int x) {return q_pow(x,mod-2);
}
void FWTxor(LL *f,int x,int len)
{for(int mid=1;(mid<<1)<=len;mid<<=1){int R=mid<<1;for(int i=0;i<len;i+=R)for(int j=0;j<mid;j++){f[i+j]=(f[i+j]+f[i+j+mid])%mod;f[i+j+mid]=(f[i+j]-f[i+j+mid]+mod-f[i+j+mid]+mod)%mod;f[i+j]=f[i+j]*x%mod;f[i+j+mid]=f[i+j+mid]*x%mod;}}
}
void solve(int l,int r) {if(l==r) {E[l]=(E[l]+(1-S[l]+mod)*invS[l])%mod;return;}int mid=(l+r)>>1,len=mid-l+1,p=l^(mid+1);solve(mid+1,r);for(int i=0;i<len;i++) {a[i]=(E[i+mid+1]+1)%mod;b[i]=P[i+p];}FWTxor(a,1,len),FWTxor(b,1,len);for(int i=0;i<len;i++) {a[i]=a[i]*b[i]%mod;}FWTxor(a,(mod+1)>>1,len);for(int i=l;i<=mid;i++) {E[i]=(E[i]+a[i-l]*inv(S[i]))%mod;}solve(l,mid);
}
int main()
{#ifndef ONLINE_JUDGE
//  freopen("data.in.txt","r",stdin);
//  freopen("data.out.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);int w;cin>>w;while(w--) {memset(tmp,0,sizeof(tmp));memset(S,0,sizeof(S));memset(E,0,sizeof(E));int sum=0;read(n);for(int i=0;i<n;i++) {read(P[i]);sum+=P[i];}sum=inv(sum);for(int i=0;i<n;i++) {P[i]=P[i]*sum%mod;}for(int i=0;i<n;i++) {for(int j=16;j>=0;j--) {if(i>>j&1) {tmp[j]=(tmp[j]+P[i])%mod;break;}}}for(int i=0;i<n;i++) {for(int j=0;j<=16;j++) {if(!(i>>j&1)) {S[i]=(S[i]+tmp[j])%mod;}}invS[i]=inv(S[i]);}solve(0,n-1);cout<<E[0]<<endl;}return 0;
}

2021牛客多校6 - Gambling Monster(分治FWT优化期望dp)相关推荐

  1. LCS(2021牛客多校4)

    LCS(2021牛客多校4) 题意: 让你构造三个字符串s1,s2,s3,长度均为n,要求LCS(s1,s2)=a,LCS(s2,s3)=b,LCS(s1,s3)=c 题解: 先考虑三个串互相LCS为 ...

  2. 【2021牛客多校2】F-Girlfriend 计算几何

    2021牛客多校2-F F-Girlfriend 题目大意 给出四个点 A , B , C , D A, B, C, D A,B,C,D 另有两点 P 1 , P 2 P_1, P_2 P1​,P2​ ...

  3. K-Stack 2021牛客多校2

    链接:https://ac.nowcoder.com/acm/contest/11253/K 来源:牛客网 题目描述 ZYT had a magic permutation a1,a2,⋯ ,an a ...

  4. 2021牛客多校第八场补题 D-OR

    链接:https://ac.nowcoder.com/acm/contest/11259/D 来源:牛客网 题目描述 There are two sequences of length n−1n-1n ...

  5. 2021牛客多校第五场补题

    B-Boxes 链接:https://ac.nowcoder.com/acm/contest/11256/B 来源:牛客网 题目描述 There're nn_{}n​ boxes in front o ...

  6. 2021牛客多校9 - Cells(推公式+NTT)

    题目链接:点击查看 题目大意:初始时给出 nnn 个点,分别为 {(0,a0),(0,a1),⋯,(0,an)}\{(0,a_0),(0,a_1),\cdots,(0,a_n)\}{(0,a0​),( ...

  7. (2021牛客多校一)A.Alice and Bob(博弈)

    样例输入: 5 2 3 3 5 5 7 7 5 7 7 Bob Alice Bob Bob Alice 题意:有两堆石子,石子数目分别为n和m,Alice和Bob轮流进行以下操作: 从一堆石子中取出k ...

  8. 【多校训练】2021牛客多校5

    [前言] 很久没有时间整理题解了,补题和打游戏的时间居多(doge) 这场其实主要F出题人数据有锅,花太多时间了(赛后重测是一血),然后后面G想歪了爆搜剪枝没过,I的回滚莫队队友前一天写了结果今天写不 ...

  9. FFT ---- 2021牛客多校第一场 H Hash Function

    题目链接 题目大意: 解题思路: 首先我们知道任意两个数%seed\%seed%seed都不相同→\rightarrow→(aj−ai)%seed≠0(∀ai≤aj)(a_j-a_i)\%seed\n ...

最新文章

  1. Hadoop源码导入Eclipse
  2. ACM - 第6章 数据结构基础(2)
  3. OpenShift 4 - 使用Operator安装Gitea
  4. C语言C++中memset()函数使用和注意事项
  5. this的作用(转)
  6. 写单例模式以及防止反射破坏
  7. 客户端的云桌面平台配置与开启(附,登录“云电脑”与切换登录账号)
  8. IEC61850和IEC60870-6(TASE.2)的比较
  9. 动环监控系统的主要功能,动环监控系统的监控对象有哪些
  10. web工程师的自我修养
  11. 掘金企服:ICP经营许可证和ICP备案的区别 1
  12. 苹果和老降噪芯片合作商分手: iPhone 5 Siri 有变?
  13. android ogg转mp3,MP3提取转换器
  14. 如何设计一个高并发的存储系统
  15. 使用python解密pdf
  16. 初学者如何选择开发语言
  17. 财务期初开账-科目余额/期初导入/期初数据/期初余额
  18. 计算机科学技术考研内容,计算机科学与技术考研考什么 具体内容有哪些
  19. 蒙古文在web浏览器竖排显示
  20. mysql 获取倒数第二_MySQL查询倒数第二条记录实现方法

热门文章

  1. DIY一个高大上带提醒的计时器,简单实用,你还在等什么
  2. php如何修改xml中element值,php修改xml节点的值
  3. android11beta支持什么手机,Android 11 Beta1发布,新增多种功能,网友:Android基于 Flyme...
  4. synchronized的基本语法
  5. 执行SQL-MapperMethod.execute()
  6. HandlerMappings
  7. 【问题2】为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?
  8. SpringMVC概述
  9. HDFS的API操作-创建文件和文件夹
  10. Servlet_体系结构