传送门:http://uoj.ac/problem/299

题目良心给了Bayes定理,但对于我这种数学渣来说并没有什么用。

先大概讲下相关数学内容:

1.定义:$P(X)$ 表示事件$X$发生的概率,$E(X)$表示随机变量$X$的期望值,$P(A|B)$表示已知$B$发生,$A$发生的概率,$P(AB)$表示$A$和$B$同时发生的概率。

2.条件概率公式:

$\begin{aligned}P(A|B)=\frac{P(AB)}{P(B)}\end{aligned}$。

由$P(B)P(A|B)=P(AB)$移项可得。

3.全概率公式:

当存在$k$个互斥事件且事件并集为全集时:

$P(A)=\sum\limits_{i=1}^{k}P(A|X=X_i)P(X=Xi)$

由条件概率公式可得。

4.Bayes定理:

$\begin{aligned}P(A|B)=\frac{P(AB)}{P(B)}=\frac{P(B|A)P(A)}{P(B)}\end{aligned}$

由条件概率公式可得。

接下来是OI部分。

对于每个位置,找到夹着它的两个已知胜负条件,设为A和B。

将A作为必要条件(题设),可知$E(C)=\sum_{i=1}^{k}P(c_i=1)$。根据Bayes公式可得$\begin{aligned}P(c_i=1|B)=\frac{P(c_i=1)P(B|c_i=1)}{P(B)}=\frac{P(c_i=1,B)}{P(B)}\end{aligned}$

修改的时候使用线段树进行区间合并,用矩阵加速合并。

设节点$x$代表的区间是$[L,R]$,则val[x][0/1][0/1]表示$L-1$为胜/负时,R为胜/负的$P(c_L=1)*P(B|c_L=1)$和$P(B)$。

接下来是暴力部分(10分)。

指数级枚举所有状态,计算这个状态出现的概率以及是否合法,累加即可。

方法一:暴力

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; const int N=;
char S[];
int n,m;
double p[N],q[N],w[]; void calc(){
double ans=,tp=;
int up=(<<n);
for(int i=;i<up;i++){
bool f=; int c=,las=; double pc=;
for(int j=,k=;j<n;j++,k++)
if(i&(<<j)){
if(w[k]==){ f=false; break; }
c++;
if (las) pc*=p[k]; else pc*=q[k];
las=;
}else{
if(w[k]==){ f=false; break; }
if(las)pc*=(-p[k]); else pc*=(-q[k]);
las=;
}
if(f)ans+=pc*c,tp+=pc;
}
ans/=tp; printf("%.6f\n",ans);
} void solve(){
for(int i=;i<=n;i++)w[i]=-;
for(int i=,x,y;i<=m;i++){
scanf("%s",S);
if(S[]=='a') scanf("%d%d",&x,&y),w[x]=y; else scanf("%d",&x),w[x]=-;
calc();
}
} int main(){
freopen("game.in","r",stdin);
freopen("game.out","w",stdout);
scanf("%d%d",&n,&m); scanf("%s",S);
scanf("%lf",&p[]);
for(int i=;i<=n;i++)scanf("%lf %lf",&p[i],&q[i]);
solve();
return ;
}

方法二:正解

 #include<set>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ls (x<<1)
#define rs (ls|1)
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
using namespace std; const int N=;
int n,m,p,c,type,S2[N];
double ans,P[N],Q[N];
set<int>S1;
char op[]; struct M{ double v[][]; M(){ memset(v,,sizeof(v)); }; };
M operator +(M a,const M &b){ rep(i,,) rep(j,,) a.v[i][j]+=b.v[i][j]; return a; }
M operator *(const M &a,const M &b){ M c; rep(i,,) rep(j,,) rep(k,,) c.v[i][j]+=a.v[i][k]*b.v[k][j]; return c; } struct inf{ M f,g; inf(const M &_f=M(),const M &_g=M()):f(_f),g(_g){}; };
inf operator +(const inf &a,const inf &b){ return inf(a.f*b.f,a.g*b.f+a.f*b.g); }
struct node{ int l,r,mid; inf val; }seg[N<<]; void build(int x,int l,int r){
if (l==r){
seg[x].val.f.v[][]=P[l]; seg[x].val.f.v[][]=.-P[l];
seg[x].val.f.v[][]=Q[l]; seg[x].val.f.v[][]=.-Q[l];
seg[x].val.g.v[][]=P[l]; seg[x].val.g.v[][]=Q[l];
return;
}
int mid=(l+r)>>;
build(ls,l,mid); build(rs,mid+,r); seg[x].val=seg[ls].val+seg[rs].val;
} inf que(int x,int L,int R,int l,int r){
if (L==l && r==R) return seg[x].val;
int mid=(L+R)>>;
if (r<=mid) return que(ls,L,mid,l,r);
else if (l>mid) return que(rs,mid+,R,l,r);
else return que(ls,L,mid,l,mid)+que(rs,mid+,R,mid+,r);
} double ask(int l,int r){ inf v=que(,,n+,l+,r); return v.g.v[S2[l]][S2[r]]/v.f.v[S2[l]][S2[r]]; } int main(){
freopen("game.in","r",stdin);
freopen("game.out","w",stdout);
scanf("%d%d",&n,&m); scanf("%s",op); scanf("%lf",&P[]);
rep(i,,n) scanf("%lf%lf",&P[i],&Q[i]);
S1.insert(); S2[]=; S1.insert(n+); S2[n+]=; P[n+]=Q[n+]=.;
build(,,n+); ans=ask(,n+);
while (m--){
scanf("%s",op);
if (*op=='a'){
scanf("%d%d",&p,&c); set<int>::iterator nxt=S1.lower_bound(p),lst=nxt; lst--;
S2[p]=c; ans-=ask(*lst,*nxt); ans+=ask(*lst,p)+ask(p,*nxt); S1.insert(p);
}else{
scanf("%d",&p); set<int>::iterator mid=S1.find(p),lst,nxt;
lst=nxt=mid; lst--; nxt++; ans-=ask(*lst,p)+ask(p,*nxt); ans+=ask(*lst,*nxt); S1.erase(p);
}
printf("%.6lf\n",ans);
}
return ;
}

[CTSC2017]游戏(Bayes定理,线段树)的更多相关文章

  1. 【BZOJ-2892&1171】强袭作战&大sz的游戏 权值线段树+单调队列+标记永久化+DP

    2892: 强袭作战 Time Limit: 50 Sec  Memory Limit: 512 MBSubmit: 45  Solved: 30[Submit][Status][Discuss] D ...

  2. 【题解】 AtCoder ARC 076 F - Exhausted? (霍尔定理+线段树)

    题面 题目大意: 给你\(m\)张椅子,排成一行,告诉你\(n\)个人,每个人可以坐的座位为\([1,l]\bigcup[r,m]\),为了让所有人坐下,问至少还要加多少张椅子. Solution: ...

  3. BZOJ.3693.圆桌会议(Hall定理 线段树)

    题目链接 先考虑链.题目相当于求是否存在完备匹配.那么由Hall定理,对于任意一个区间[L,R],都要满足[li,ri]完全在[L,R]中的ai之和sum小于等于总位置数,即R-L+1.(其实用不到H ...

  4. LOJ.6062.[2017山东一轮集训]Pair(Hall定理 线段树)

    题目链接 首先Bi之间的大小关系没用,先对它排序,假设从小到大排 那么每个Ai所能匹配的Bi就是一个B[]的后缀 把一个B[]后缀的匹配看做一条边的覆盖,设Xi为Bi被覆盖的次数 容易想到 对于每个i ...

  5. loj#6062. 「2017 山东一轮集训 Day2」Pair hall定理+线段树

    题意:给出一个长度为 n的数列 a和一个长度为 m 的数列 b,求 a有多少个长度为 m的连续子数列能与 b匹配.两个数列可以匹配,当且仅当存在一种方案,使两个数列中的数可以两两配对,两个数可以配对当 ...

  6. [BZOJ3693]圆桌会议[霍尔定理+线段树]

    题意 题目链接 分析 又是一个二分图匹配的问题,考虑霍尔定理. 根据套路我们知道只需要检查 "区间的并是一段连续的区间" 这些子集. 首先将环倍长.考虑枚举答案的区间并的右端点 \ ...

  7. [BZOJ2138]stone[霍尔定理+线段树]

    题意 一共有 \(n\) 堆石子,每堆石子有一个数量 \(a\) ,你要进行 \(m\) 次操作,每次操作你可以在满足前 \(i-1\) 次操作的回答的基础上选择在 \([L_i,R_i]\) 区间中 ...

  8. BZOJ3693: 圆桌会议(Hall定理 线段树)

    题意 题目链接 Sol 好的又是神仙题... 我的思路:对于区间分两种情况讨论,一种是完全包含,另一种是部分包含.第一种情况非常好判断,至于计算对于一个区间[l, r]的$\sum a[i]$就可以了 ...

  9. 模拟赛 怨灵退治 题解(Hall定理+线段树)

    题意: 有 n 群怨灵排成一排,燐每秒钟会选择一段区间,消灭至多 k 只怨灵. 如果怨灵数量不足 k,则会消灭尽量多的怨灵. 燐作为一只有特点的猫,它选择的区间是不会相互包含的.它想要知道它每秒最多能 ...

随机推荐

  1. hadoop基础----hadoop实战(七)-----hadoop管理工具---使用Cloudera Manager安装Hadoop---Cloudera Manager和CDH5.8离线安装

    hadoop基础----hadoop实战(六)-----hadoop管理工具---Cloudera Manager---CDH介绍 简介 我们在上篇文章中已经了解了CDH,为了后续的学习,我们本章就来 ...

  2. 用PHP迭代器来实现一个斐波纳契数列

    斐波纳契数列通常做法是用递归实现,当然还有其它的方法.这里现学现卖,用PHP的迭代器来实现一个斐波纳契数列,几乎没有什么难度,只是把类里的next()方法重写了一次.注释已经写到代码中,也是相当好理解 ...

  3. POJ2253:Frogger(改造Dijkstra)

    Frogger Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 64864   Accepted: 20127 题目链接:ht ...

  4. Codeforces Round #487 (Div. 2) A Mist of Florescence (暴力构造)

    C. A Mist of Florescence time limit per test 1 second memory limit per test 256 megabytes input stan ...

  5. bzoj 1110 [POI2007]砝码Odw 贪心+进制转化

    [POI2007]砝码Odw Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 661  Solved: 366[Submit][Status][Disc ...

  6. Linux Uptime 命令,让你知道你的系统运行了多久

    对于一些人来说系统运行了多久是无关紧要的,但是对于服务器管理员来说,这是相当重要的信息.服务器在运行重要应用的时候,必须尽量保证长时间的稳定运行,有时候甚至要求零宕机.那么我们怎么才能知道服务器运行了 ...

  7. 【转载】深入理解PHP Opcode缓存原理

    转载地址:深入理解PHP Opcode缓存原理 什么是opcode缓存? 当解释器完成对脚本代码的分析后,便将它们生成可以直接运行的中间代码,也称为操作码(Operate Code,opcode).O ...

  8. 关于javascript中的this 一段小实例深有体会啊

    先声明鄙人正在努力的把脚抬进门来,说的都是比较粗浅的知识,但都是我实践中得出的体会,很深刻.  正在自学中挣扎的DOG. 先看段代码: function highlightRows() { if(!d ...

  9. nginx的常规配置

    程序员们,在北上广你还能买房吗? >>>   nginx的常规配置 nginx的使用非常简单,只需要配置好我们需要的各种指令,就能跑起来.如果你需要添加模块,还需要添加模块方面的配 ...

  10. 【poj3294-不小于k个字符串中最长公共子串】后缀数组

    1.注意每两个串之间的连接符要不一样. 2.分组的时候要注意最后一组啊!又漏了! 3.开数组要考虑连接符的数量.100010是不够的至少要101000. #include<cstdio> ...