zoukankan      html  css  js  c++  java
  • 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
    ", 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 }
    View Code
  • 相关阅读:
    SGU 495 Kids and Prizes 概率DP 或 数学推理
    poj 2799 IP Networks 模拟 位运算
    uva 202 Repeating Decimals 模拟
    poj 3158 Kickdown 字符串匹配?
    uva 1595 Symmetry 暴力
    uva 201 Squares 暴力
    uva 1594 Ducci Sequence 哈希
    uva 1368 DNA Consensus String 字符串
    数字、字符串、列表的常用操作
    if条件判断 流程控制
  • 原文地址:https://www.cnblogs.com/y7070/p/5042928.html
Copyright © 2011-2022 走看看