【2016北京集训测试赛】azelso(unfinished)

[吐槽]

  首先当然是要orzyww啦

  以及orzyxq奇妙顺推很强qwq

  嗯。。怎么说呢虽然说之前零零散散做了一些概d的题目但是总感觉好像并没有弄得比较明白啊。。(我的妈果然蒟蒻)

  这题的话可以说是难得的一道搞得比较清楚的概d题目吧记录一下还是挺有意思的ovo

  当然咯。。显然考场上并没有推出来。。嗯qwq

[题解]

  看到说要求期望的距离,然后总的长度又被分成了一段一段的(各个事件)

  所以就有一个比较直接的想法:将每一段期望走的次数算出来然后再乘上每一段的距离,加起来就是答案啦

  那么现在问题来了怎么求期望走的次数

  

  考虑定义

  e[i]:第i个到第i+1个事件中间这段路程的经过次数的期望

  f[i]:第i个事件发生后走到h,并且i到i+1中间这段路程只经过了一次的概率

  根据定义我们可以得到:e[i]=1/f[i]

  (然而为啥要这样搞呢。。嗯个人的理解是如果直接求期望会比较麻烦但是概率的话相对来说比较好写转移方程)

  考虑转移

  【奇妙套路】嗯概d的题目一般反着推会比较友善至于原因是啥。。还得求教各位dalao。。

  所以这题我们也反着推咯

  首先记第i+1个事件发生的概率为p,那么第i+1个事件有两种不同的情况:

  1.打怪

  如果说第i+1个事件要打怪,因为这段只能经过一次,所以显然打怪必须成功

  (否则肯定会回到前面去,那么i到i+1就会经过不止一次了)

  所以得到:i+1==X的话,f[i]=f[i+1]*p

  2.插旗

  但是如果说第i+1个事件是插旗,就会比较复杂了

  因为现在只要求i到i+1这段经过1次,对后面的情况并没有限制,所以i+1以及后面的都可以经过很多次

  换句话来说就是:只要第i+1这个位置插旗成功,后面的无论爆炸了多少次都没有关系,因为最前只能回到i+1这个位置

  

  后面被打回来的概率的话,因为被打回来了所以显然i+1到i+2经过了不止一次,那么一次被打回来的概率就是1-f[i+1]

  然后无论被打回来了多少次,最后一次肯定是要走到终点去的,所以最后要乘一个f[i+1]

  

  那么我们就可以得到:

  i+1==F的话

  f[i]=f[i+1]+p*(1-f[i+1])*f[i+1]+(p*(1-f[i+1]))^2*f[i+1]+(p*(1-f[i+1]))^3*f[i+1]+...+(p*(1-f[i+1]))^n*f[i+1]

  (爆炸0次+爆炸1次+爆炸2次+...+爆炸n次)

  这里n->正无穷

  

  考虑怎么算

  但是发现插旗的情况,式子十分不友善。。所以就整理一下

  先将f[i+1]提出来得到:

  然后发现后面的一堆其实是这种形式:

  我们记这个式子ans为a

  那么a*x=

  两式相减一下整理得到:

  a=(1-x^n-1)/(1-x)

  注意到,这里我们的x是一个概率,所以是小于1的,而n->正无穷,所以x^n-1是一个特别小的数可以直接忽略

  所以得到:a=1/(1-x)

  (mark:嗯有空可以去研究一下泰勒展开之类的)

  然后就可以带进去算啦,得到:

  f[i]=f[i+1]*1/(1-p*(1-f[i+1]))

  考虑转成e[i]的转移方程

  手头上两条式子:

  i+1打怪:f[i]=f[i+1]*p

  i+1插旗:f[i]=f[i+1]*1/(1-p*(1-f[i+1]))

  将e[i]=1/f[i]带进去得到:

  打怪:e[i]=e[i+1]/p

  插旗:e[i]=(1-p)*e[i+1]+p

  随后乘一下什么的算算答案就好

  (所以说为啥这题我写了这么长的题解。。很迷啊。。果然太菜qwq)

[坑点]

  除法的话用逆元就好啦

  但是要多% (不然怕是要被续)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #define MOD 1000000007
 5 #define ll long long
 6 using namespace std;
 7 const int MAXN=1e5+10;
 8 ll e[MAXN],p[MAXN],dis[MAXN];
 9 char op[MAXN];
10 ll ans;
11 ll n,m;
12 ll ksm(ll x,int b);
13 ll inv(ll x);
14
15 int main()
16 {
17     char s[5];
18     ll x,y;
19     scanf("%lld%lld",&n,&m);
20     for (int i=1;i<=m;++i)
21     {
22         scanf("%s%lld%lld%lld",s,&dis[i],&x,&y);
23         x=x%MOD;
24         y=y%MOD;
25         p[i]=x*inv(y)%MOD;
26         op[i]=s[0];
27     }
28     e[m]=1;
29     for (int i=m-1;i>=0;--i)
30     {
31         if (op[i+1]==‘X‘)
32             e[i]=(e[i+1]*inv(p[i+1]))%MOD;
33         else
34             e[i]=((((1+MOD-p[i+1])%MOD)*e[i+1])%MOD+p[i+1])%MOD;
35     }
36     dis[0]=0; dis[m+1]=n;
37     for (int i=0;i<=m;++i)
38         ans=(ans+(((dis[i+1]-dis[i])%MOD)*e[i])%MOD)%MOD;
39     printf("%lld\n",ans);
40 }
41
42 ll ksm(ll x,int b)
43 {
44     ll ret=1,base=x;
45     while (b)
46     {
47         if (b&1) ret=(ret*base)%MOD;
48         base=(base*base)%MOD;
49         b>>=1;
50     }
51     return ret;
52 }
53
54 ll inv(ll x)
55 {
56     return ksm(x,MOD-2);
57 }

时间: 2024-11-07 17:35:33

【2016北京集训测试赛】azelso(unfinished)的相关文章

【2016北京集训测试赛(八)】 crash的数列

Description 题解 题目说这是一个具有神奇特性的数列!这句话是非常有用的因为我们发现,如果套着这个数列的定义再从原数列引出一个新数列,它居然还是一样的...... 于是我们就想到了能不能用多点数列套着来加速转移呢? 但是发现好像太多数列套起来是可以烦死人的...... 我们就采用嵌套两次吧,记原数列为A,第一层嵌套为B,第二层嵌套为C. 我们其实可以发现一些规律,对于Ci,它对应了B中i的个数:对于Bi,它对应了A中i的个数. 稍加处理即可,我们一边计算一边模拟数列的运算,同时可以计算

【2016北京集训测试赛(八)】直径

注意:时限更改为4s 题解 考虑最原始的直径求法:找到离根节点(或离其他任意一点)最远的节点far1,再从far1出发找到离far1最远的节点far2,far1至far2的距离即为直径. 题目中提到了将原树的子树复制成新子树这一操作,显然如果我们将子树真正复制出来是会爆炸的. 实际上我们可以将每棵新子树中,真正有用的节点提取出来,以简化每个子树的结构,再按照题目的要求连接各个新子树. 我们用虚树来重构每一棵子树.每棵子树的虚树的关键点应至少包含: 子树的根节点. 这棵子树内部的直径的两端节点.

【2016北京集训测试赛(七)】自动机 (思考题)

Time Limit: 1000 ms Memory Limit: 256 MB Description Solution 这是一道看起来令人毫无头绪的题,然而确实十分简单巧妙TAT. 题目要求所有点执行相同指令后都回到初始状态. 我们先来考虑只有两种状态的情况:初始状态$T_0$与另一个状态$T_x$. 这样,我们可以通过一个二元记忆化深搜,来得到一种方案A,使得$T_0$回到$T_0$,且$T_x$回到$T_0$.如果这个方案都不存在,那么此时无解. 现在我们知道,执行方案A后,$T_x$与

【2016北京集训测试赛】river

HINT 注意是全程不能经过两个相同的景点,并且一天的开始和结束不能用同样的交通方式. [吐槽] 嗯..看到这题的想法的话..先想到了每个点的度为2,然后就有点不知所措了 隐隐约约想到了网络流,但并没有继续往下想了... 听完学长的讲评之后(%xj)个人觉得建图还是很有意思的ovo [题解] 因为每个点到对面都有k种方式,那就想到每个点原来的点$x_0$拆成k个点$x_1$, $x_2$, $x_3$... $x_k$ 然后很自然地$x_0$和拆成的点之间要连边 容量的话,因为hint里面的限制

2016北京集训测试赛(十七)- 小结

先说一下总体的情况. 场上期望得分 50 + 40 + 30 = 120 , 最后得分 50 + 0 + 30 = 80 , 实际上自己能力所及能做到的 50 + 65 + 30 = 145 分. 第二题爆零是因为我开始写了一个做法, 后来发现这个做法是错的, 然后开始随机化, 调着调着突然发现只有一分钟了, 然后自己把之前调的改回来, 然后发现怎么全都输出 0 ??? Excuse me ?? 原本不用随机化的做法可以拿 40 分, 如果结合上暴力就有 65 了. 这几天打起比赛来还是暴露了许

[2016北京集训测试赛(一)]奇怪的树-[树链剖分]

Description Solution 对于操作1,不论选了哪个点为a,最后反转颜色的点集都只有两种类型(显然啦). 暴力解法:对每个操作3,从a向上直到根节点,每到一个节点记录(它父亲的黑点数减去自己的黑点数)*父亲节点的编号.另外,还要记录a子树内的黑点.. 这种O(n2)的做法肯定会爆,考虑优化.由于这是一棵静态树,考虑树链剖分. 需要记录一个数组re[x][0/1][0/1].第2维表示深度的奇偶,第3维表示点的颜色.例如:re[x][0][0]记录的是初始情况下以x为根的子树中深度为

[2016北京集训测试赛(五)]打地鼠-[思考题]

Description Solution 我们先只考虑一只地鼠的情况,依题意得,在某一个时刻该地鼠的可能停留位置是一个公差为2的等差数列.我们设这个等差数列的两端为[L,R].则如果区间[L+1,R-1]的格子被打实际上是不会影响L和R的(列一个等差数列实际模拟一下就发现啦).而如果格子L被打,则L+2:如果格子R被打,则R-2.打了格子后,别忘了L--,R++. 嗯根据以上性质,我们可以知道,地鼠1,3,5,7,9...的L是非递减的,地鼠2,4,6,8,10...的L也是非递减的. 然后看一

[2016北京集训测试赛15]statement-[线段树+拆环]

Description Solution 由于题目要求,将a[i]->b[i](边权为i)后所得的图应该是由森林和环套树组合而成. 假如是树形结构,所有的t[i]就直接在线段树t[i]点的dfs序(即in[t[i]],out[t[i]]区间)处记录t[i]点的深度. 这样,针对所有的f[i],在线段树上查找所有包含in[f[i]]点的区间所记录的最大深度d.(这个深度就是在离f[i]最近并且已经验证了是真命题的祖先的深度) 然后用倍增算出f[i]向上到深度d,所经过的编号最大值c.ans=min

[2016北京集训测试赛17]crash的游戏-[组合数+斯特林数+拉格朗日插值]

Description Solution 核心思想是把组合数当成一个奇怪的多项式,然后拉格朗日插值..:哦对了,还要用到第二类斯特林数(就是把若干个球放到若干个盒子)的一个公式: $x^{n}=\sum _{i=0}^{n}C(n,i)*i!*S(i,x)$ 围观大佬博客(qaq公式太难打了) Code #include<iostream> #include<cstdio> #include<cstring> #include<cmath> using na