Tsinsen-A1490 osu! 【数学期望】

问题描述

  osu!是一个基于《押忍!战斗!应援团》《精英节拍特工》《太鼓达人》等各种音乐游戏做成的一款独特的PC版音乐游戏。游戏中,玩家需要根据音乐的节奏,通过鼠标点击或敲击按键合成一首歌曲。
  一张osu!的地图是由若干个“音”排列而成的。在本题中,对于每个音我们只需要考虑成功点击和错过(miss)这两种情况。对于一张osu!地图,玩家的完成情况可以用一个01串表示(0代表miss,1代表成功)。在本题中,使用如下计分规则:将玩家完成一张地图的01串中所有的0删去,则这个串可能会断裂成若干段连续的1。对于一段长度为L的1(L≥1),你的总分会增加L^2+L+1。例如:一张地图有10个音,某玩家完成情况为1011101110,则删除所有0后得到的是“1”“111”和“111”。因此这个玩家的得分为(1+1+1)+(9+3+1)+(9+3+1)=29。
  ACMonster要给Sandytea出一张osu!的地图。在一张图中,不同音对于Sandytea而言难度可能是不同的。我们定义一个音的难度系数为Sandytea成功完成这个音的概率,因此这个难度系数是介于0和1之间的。
  现在ACMonster写下了一个包含N个音的序列,但是他不想直接把这个序列做成地图,而是选择其中的某个片段。设S(X,Y)代表序列上第X个音到第Y个音构成的序列,ACMonster想知道如果把S(X,Y)对应的序列做成地图,Sandytea的期望得分是多少。有时ACMonster会觉得某个音的难度系数不太合理,因此要进行修改。请你想办法处理ACMonster的修改,并回答他提出的问题。

输入格式

  第一行包含两个数N和M,N代表序列中音的个数,M代表询问及修改的总次数。
  第二行至第(N+1)行每行包含一个实数,第i行的实数表示第(i-1)个音的难度系数。
  第(N+2)行至第(N+M+1)行每行包含三个数Type,X和Y。
  如果Type=0,代表ACMonster询问S(X,Y)的期望得分,保证X和Y为整数,1≤X≤Y≤N。
  如果Type=1,代表ACMonster要把第X个音的难度系数修改为Y,保证X为整数,1≤X≤N,0≤Y≤1。

输出格式

  对于输入中所有询问,按照出现的顺序输出相应的答案,四舍五入保留两位小数。

样例输入

2 3
0.5
0.5
0 1 2
1 1 0
0 1 2

样例输出

3.25
1.50

样例说明

  对于第一次询问,00,01,10,11这四种情况出现的概率均为1/4,得分分别为0,3,3,7。因此期望得分为(0+3+3+7)/4=3.25。
  对于第二次询问,00,01这两种情况出现的概率均为1/2,得分分别为0,3。因此期望得分为(0+3)/2=1.50。

数据规模和约定

  20%的数据满足N,M≤5000;
  60%的数据满足N,M≤50000;
  100%的数据满足N,M≤500000。

题解

  我们要求的是E(L^2 + L + 1),我们先按照之前的方法试一试,设sum[i]表示到第i位这个值的答案是E(L^2 + L + 1),那么我们依旧这样写sum[i] = sum[i - 1] + pi * ?         ? = 2E(L) + 2。

  但是这样是不对的,这样的话我们发现我们把0这样的?当成了1。

  以下正解:

    E(L^2) + E(L) + E(1),应为这些都是得分,sum[i] = sum[i - 1] + pi * ?。

    剩下的就是乔明达大爷的题解了,我就不写了。

 1 #include <bits/stdc++.h>
 2 #define rep(i, a, b) for (int i = a; i <= b; i++)
 3 #define drep(i, a, b) for (int i = a; i >= b; i--)
 4 #define REP(i, a, b) for (int i = a; i < b; i++)
 5 #define mp make_pair
 6 #define pb push_back
 7 #define clr(x) memset(x, 0, sizeof(x))
 8 #define xx first
 9 #define yy second
10 using namespace std;
11 typedef long long i64;
12 typedef pair<int, int> pii;
13 const int  inf = ~0U >> 1;
14 const i64 INF = ~0ULL >> 1;
15 //*******************************
16
17 const int maxn = 500005;
18
19 struct node {
20     double p;
21     double a21, a22, a31, a32;
22     double mul1;
23     node() {}
24     node(double _p, double _a21, double _a22, double _a31, double _a32, double _mul1) :
25         p(_p), a21(_a21), a22(_a22), a31(_a31), a32(_a32), mul1(_mul1) {}
26
27 };
28
29 double ans0, ans1, ans3[3];
30
31 /* the matrix
32    {sum[i - 1], E[i - 1], 1} * {1  , 0 , 0} = {sum[i], E[i], 1}
33                                {2pi, pi, 0}
34                                {pi , pi, 1}
35  */
36
37 double pi[maxn];
38
39 struct Seg_Tree {
40     node T[maxn << 2];
41
42     void Push_up(int o) {
43         T[o].p = T[o << 1].p + T[o << 1 | 1].p, T[o].mul1 = T[o << 1].mul1 + T[o << 1 | 1].mul1;
44         T[o].a21 = T[o << 1].a21 + T[o << 1].a22 * T[o << 1 | 1].a21;
45         T[o].a22 = T[o << 1].a22 * T[o << 1| 1].a22;
46         T[o].a31 = T[o << 1].a31 + T[o << 1].a32 * T[o << 1 | 1].a21 + T[o << 1 | 1].a31;
47         T[o].a32 = T[o << 1].a32 * T[o << 1 | 1].a22 + T[o << 1 | 1].a32;
48     }
49
50     void update(int o, int l, int r, int x, double p) {
51         if (l == r) {
52             T[o] = node(p, 2 * p, p, p, p, (1 - pi[l - 1]) * p);
53             return;
54         }
55         int mid = l + r >> 1;
56         if (x > mid) update(o << 1 | 1, mid + 1, r, x, p);
57         else update(o << 1, l, mid, x, p);
58         Push_up(o);
59     }
60
61     void query(int o, int l, int r, int ql, int qr) {
62         if (ql <= l && r <= qr) {
63             ans1 += T[o].p;
64             ans0 += T[o].mul1;
65             ans3[1] = ans3[1] + ans3[2] * T[o].a21 + T[o].a31;
66             ans3[2] = ans3[2] * T[o].a22 + T[o].a32;
67             return;
68         }
69         int mid = l + r >> 1;
70         if (ql <= mid) query(o << 1, l, mid, ql, qr);
71         if (qr > mid) query(o << 1 | 1, mid + 1, r, ql, qr);
72     }
73 } T;
74
75 int main() {
76     int n, m;
77     scanf("%d%d", &n, &m);
78     rep(i, 1, n) scanf("%lf", &pi[i]), T.update(1, 1, n, i, pi[i]);
79     while (m--) {
80         int op;
81         scanf("%d", &op);
82         if (!op) {
83             int x, y; scanf("%d%d", &x, &y);
84             ans1 = 0, ans0 = 0, ans3[1] = ans3[2] = 0;
85             T.query(1, 1, n, x, y);
86             printf("%.2lf\n", ans1 + ans0 + pi[x - 1] * pi[x] + ans3[1]);
87         }
88         else {
89             double w; int x;
90             scanf("%d%lf", &x, &w);
91             pi[x] = w, T.update(1, 1, n, x, w);
92             if (x != n) T.update(1, 1, n, x + 1, pi[x + 1]);
93         }
94     }
95     return 0;
96 }

时间: 2024-10-04 17:34:47

Tsinsen-A1490 osu! 【数学期望】的相关文章

数学期望

数学期望又称均值(加权均值),例如 甲8环,9环,10环的概率分别为0.1,0.8,0.1,即权重,则加权均值为8*0.1+9*0.8+10*0.1=9:同理乙的加权均值为8.95 则甲的平均成绩优于乙 对于离散型随机变量 连续型随机变量

数学1——概率与数学期望

1.什么是数学期望? 数学期望亦称期望.期望值等.在概率论和统计学中,一个离散型随机变量的期望值是试验中每一次可能出现的结果的概率乘以其结果的总和. 这是什么意思呢?假如我们来玩一个游戏,一共52张牌,其中有4个A.我们1元钱赌一把,如果你抽中了A,那么我给你10元钱,否则你的1元钱就输给我了.在这个游戏中,抽中的概率是$\frac{1}{13} ( \frac{4}{52} ) $,结果是赢10元钱:抽不中概率是$\frac{12}{13}$,结果是亏1元钱.那么你赢的概率,也就是期望值是$-

poj3682:数学期望,O(1)做法附推导过程

这几天一直在磨蹭这题..第一个答案很容易,但在第二个答案我无法算出来了,于是只好求助于Zayin.Zayin又求助于我们年级里面的一个研究生数学老师..而现在终于算出来了,我看了看,自己也推出来几次了,先看题:) King Arthur's Birthday Celebration Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 2921 Accepted: 926 Description King Arthur is an

HDUBoard Game Dice (数学期望)

推出的公式是M^x*x/N,大概意思是M^x*x这些种可能后一定会找出一个裁判,在除以N为数学期望. 可能和数学公式还有关系. #include<stdio.h> #include<math.h> __int64 gcd(__int64 a,__int64 b){ return b == 0 ? a : gcd(b, a%b); } int main() { __int64 i,j,n,m,t,x,a,b,temp,sum; scanf("%I64d",&

HDU 4405 飞行棋上的数学期望

突然发现每次出现有关数学期望的题目都不会做,就只能找些虽然水但自己还是做不出的算数学期望的水题练练手了 题目大意: 从起点0点开始到达点n,通过每次掷色子前进,可扔出1,2,3,4,5,6这6种情况,扔到几前进几,当然对应飞行通道可以通过x直达一点y,x<y,计算到达n点或超过n 点要扔色子的次数的数学期望 从某一点 i 扔完色子可到达 i+1,i+2,i+3,i+4,i+5,i+6这6个点,令dp[i]为到达末尾的数学期望 那么到达之后6个点的数学期望是一样的,那么dp[i]=dp[i+1]*

概率论,简要数学期望(转载)

概率论(https://ruanx.pw/post/%E6%A6%82%E7%8E%87%E8%AE%BA.html) 这东西并不难学.这片博客主要介绍离散概率.连续概率.期望与微积分…… 离散型概率入门 计算方法 首先,我们来讨论一个最原始的问题:抛一个质地均匀的硬币,抛中正面的几率是多大?显然50%50%. 那么问题加深一番:抛两个质地均匀的硬币,都抛中正面的几率是多大?显然25%25%. 进一步,抛nn个硬币,全都正面朝上的几率是0.5×0.5×0.5?=0.5n0.5×0.5×0.5?=

HDU3910(数学期望题,题目难懂)

Liang Guo Sha Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 590    Accepted Submission(s): 426 Problem Description Maybe you know “San Guo Sha”, but I guess you didn’t hear the game: “Liang Gu

[sdut]2623+[sdut]2878//四五届省赛中的两道数学期望

两道数学期望的题今天一起总结上来. 1.the number of steps(第四届省赛) 1 #include <iostream> 2 #include <string.h> 3 #include <iomanip> 4 using namespace std; 5 double dp[100][100]; 6 int n; 7 double a,b,c,d,e; 8 9 int main() 10 { 11 while(cin>>n&&

ZOJ3329-One Person Game(概率DP求数学期望)

One Person Game Time Limit: 1 Second      Memory Limit: 32768 KB      Special Judge There is a very simple and interesting one-person game. You have 3 dice, namelyDie1, Die2 and Die3. Die1 hasK1 faces. Die2 has K2 faces.Die3 has K3 faces. All the dic

UVa 1639 Candy (数学期望+组合数学+高精度存储)

题意:有两个盒子各有n个糖,每次随机选一个(概率分别为p,1-p),然后吃掉,直到有一次,你打开盒子发现,没糖了! 输入n,p,求另一个盒子里糖的个数的数学期望. 析:先不说这个题多坑,首先要用long double来实现高精度,我先用的double一直WA,后来看了题解是用long double, 改了,可一直改不对,怎么输出结果都是-2.00000,搞了一晚上,真是无语,因为我输入输出数据类型是long double, 结果一直不对 ,可能是我的编译器是C89的吧,和C语言,输入输出格式不同