校内模拟赛 Zbq's Music Challenge

Zbq‘s Music Challenge

题意

  一个长度为n的序列,每个位置可能是1或者0,1的概率是$p_i$。对于一个序列$S$,它的得分是

$$BasicScore=A\times \sum_{i=1}^{n}{S_i} \tag{1}$$

$$ combo(i)=\left\{ \begin{aligned} &S_i & &i=1 \\ &combo(i-1)+1 & &i\neq 1 ~\mathrm{and}~ S_i=1 \\ &combo(i-1)\times t & &\mathrm{otherwise} \end{aligned} \tag{2} \right.$$

$$ComboScore=B\times \sum_{i=1}^{n}{S_i\times combo(i)} \tag{3}$$

$$TotalScore=BasicScore+ComboScore \tag{4}$$

  两种操作,修改每个位置的概率,询问一段区间得分的期望,答案对$998244353$取模。

分析

  分成两部分算,$BasicScore$可以对$p_i$求和得到。

  对于每段区间,$f[i]$设第i位置数字期望是多少,那么$ComboScore = B \times \sum\limits_{i=l}^{r} p_i \times (f[i-1] + 1) $。

  然后转移可以写成矩阵的形式。

  $$ \left[ \begin{matrix} 0 & p_i & p_i \\ 0 & (1 - p_i) \times t + p_i & p_i\\ 0 & 0 & 1 \end{matrix} \right] \times \left[ \begin{matrix} sum\\ f[i - 1]\\ 1 \end{matrix} \right] = \left[ \begin{matrix} sum‘ \\ f[i]\\ 1 \end{matrix} \right] $$

  于是,线段树维护一下即可。复杂度$O(nlogn \times 3^3)$

代码

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cctype>
#include<cmath>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
using namespace std;
typedef long long LL;

inline int read() {
    int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch==‘-‘)f=-1;
    for(;isdigit(ch);ch=getchar())x=x*10+ch-‘0‘;return x*f;
}

const int mod = 998244353;
const int N = 500005;
int p[N];

int ksm(int a,int b) {
    int res = 1;
    while (b) {
        if (b & 1) res = 1ll * res * a % mod;
        a = 1ll * a * a % mod;
        b >>= 1;
    }
    return res;
}
int fen(int a,int b) { return 1ll * a * ksm(b, mod - 2) % mod; }

int sum[N << 2], tt, NowAns, n, A, B;
struct Mat{
    int a[3][3];
    Mat() { memset(a, 0, sizeof(a)); }
    void set(int p) {
        a[0][0] = 1;
        a[0][1] = a[0][2] = a[1][2] = p;
        a[1][1] = (1ll * (mod + 1 - p) % mod * tt % mod + p) % mod;
        a[2][2] = 1;
    }
}T[N << 2];
Mat operator * (const Mat &A, const Mat &B) {
    Mat C;
    for (int k = 0; k < 3; ++k)
        for (int i = 0; i < 3; ++i)
            for (int j = 0; j < 3; ++j)
                C.a[i][j] = (C.a[i][j] + 1ll * A.a[i][k] * B.a[k][j] % mod) % mod;
    return C;
}
inline void pushup(int rt) {
    T[rt] = T[rt << 1] * T[rt << 1 | 1];
    sum[rt] = (sum[rt << 1] + sum[rt << 1 | 1]) % mod;
}
void build(int l,int r,int rt) {
    if (l == r) {
        T[rt].set(p[l]); sum[rt] = p[l]; return ;
    }
    int mid = (l + r) >> 1;
    build(l, mid, rt << 1); build(mid + 1, r, rt << 1 | 1);
    pushup(rt);
}
void update(int l,int r,int rt,int pos) {
    if (l == r) {
        T[rt].set(p[l]); sum[rt] = p[l]; return ;
    }
    int mid = (l + r) >> 1;
    if (pos <= mid) update(l, mid, rt << 1, pos);
    else update(mid + 1, r, rt << 1 | 1, pos);
    pushup(rt);
}
Mat query(int l,int r,int rt,int L,int R) {
    if (L <= l && r <= R) { NowAns = (NowAns + sum[rt]) % mod; return T[rt]; }
    int mid = (l + r) >> 1;
    if (R <= mid) return query(l, mid, rt << 1, L, R);
    else if (L > mid) return query(mid + 1, r, rt << 1 | 1, L, R);
    else return query(l, mid, rt << 1, L, R) * query(mid + 1, r, rt << 1 | 1, L, R);
}
void query() {
    int x = read(), y = read();
    NowAns = 0;
    Mat now = query(1, n, 1, x, y);
    LL ans1 = NowAns, ans2 = now.a[0][2];
    cout << (1ll * ans1 * A % mod + 1ll * ans2 * B % mod) % mod << "\n";
}
int main() {
    read();
    n = read();int Q = read(), ta = read(), tb = read();A = read(), B = read();
    tt = fen(ta, tb);
    for (int i = 1; i <= n; ++i)
        ta = read(), tb = read(), p[i] = fen(ta, tb);
    build(1, n, 1);
    while (Q --) {
        if (read()) query();
        else {
            int x = read(), ta = read(), tb = read();
            p[x] = fen(ta, tb);
            update(1, n, 1, x);
        }
    }
    return 0;
}

校内模拟赛 Zbq's Music Challenge

原文地址:https://www.cnblogs.com/mjtcn/p/10651188.html

时间: 2024-10-08 12:48:23

校内模拟赛 Zbq's Music Challenge的相关文章

2017.6.11 校内模拟赛

题面及数据及std(有本人的也有原来的) :2017.6.11 校内模拟赛 T1 自己在纸上模拟一下后就会发现 可以用栈来搞一搞事情 受了上次zsq 讲的双栈排序的启发.. 具体就是将原盘子大小copy一下排个序 用两个指针维护两个数组(原数据 和 排序后的数据), 即分为1数据和2数组 将小于1指针指向的数据的2数组中的数据全部压入栈中 后进行消除, 将栈栈顶元素与当前1数组中的1指针指向的元素进行比较 相同则消除 后重复过程 直至指针超过N 后判断一下是否两个指针都超过了N... #incl

[20180816]校内模拟赛

T1 清理(clear) 问题描述 小 C 最近自己开发了一款云盘软件,目前已有??个用户.小C 的云盘上的文件会被后台分成两种类型,活动 文件和非活动文件,活动文件即可能常用的文件,会被放在高速服务器上给用户提供高速下载服务.用户 上传一个文件时,这个文件会被设置为活动文件.由于高速服务器内存大小有限,小 C 需要把一些文件 设为非活动文件,有以下两种设置方式:1.把上传时间前??早的文件全部设为非活动文件:2.把第??个用户上 传的文件全部设为非活动文件.注意这两种方式操作的对象都是所有文件

校内模拟赛T1大美江湖

这就是一个模拟题,注意1234分别对应左右上下横坐标和纵坐标的判断就好了 题解: 需要注意的是,向上取整ceil函数是对于一个double值返回一个double值,也就是说在ceil里面的类型一定要是double,否则会炸 代码: #include<cstdio> #include<iostream> #include<cstdlib> #include<cmath> #include<cstring> #include<string>

2019/8/27 校内模拟赛 考试报告

A.挑战(challenge.cpp) 首先令\(x_i=max(a_i-k,0)\),即破坏第\(i\)个防御区域的代价. 设\(dp_i\)表示从\(1...i\)需要的最小代价,有状态转移方程:\(dp_i=min(dp_j)+x_i\),其中\(i-L\le j\le i-1\). 初始化边界\(dp_0=0,dp_{1...n+1}=inf\).动态规划求出\(dp_{n+1}\)即可. 时间复杂度\(O(n^2)\),可以用ST表/线段树优化到\(O(nlogn)\). B.乌龟(t

校内模拟赛:确定小组

  [问题描述] 有n个人坐成一排,这n个人都在某一个小组中,同一个小组的所有人所坐的位置一定是连续的. 有一个记者在现场进行采访,他每次采访都会询问一个人其所在的小组有多少人,被询问的每个人都给出了正确的答案,但是由于时间仓促,记者不一定询问了每个人,我们记录一个长度为n的答案序列,序列的第i个数表示第i个人的回答,如果为0则表示记者没有询问过这个人. 记者发现,对于一些情况,他可以唯一确定这排所有人的分组,而对于另外一些情况则不能,于是记者开始好奇,对于某一个答案序列,他能不能做到这一点,如

校内模拟赛20170604

香蕉锤--双向链表 #include<iostream> #include<cstdio> using namespace std; inline int read(){ int num=0,t=1;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')t=-1;c=getchar();} while(c>='0'&&c<='9'){num=num*10+c-'0';c=getchar();} ret

5.13 校内模拟赛

... 果然是dalao们做难题做多了后 简单题水不起来了吗.. 5.13解题报告 300分 T1写了差不多30~40分钟 T2写了不到5min (当时怀疑有坑..) T3推了大概1个多小时的式子, 然后又加上调试差不多一个半小时 时间分配就这样..感觉T2出的太过简单了..直接是个模板 T1 并查集 + 乱搞 T2 快速幂模板 T3 Dp T1 : codevs 2796 最小完全图 二次联通门 : codevs 2796 最小完全图 /* codevs 2796 最小完全图 并查集 + 乱搞

校内模拟赛(20170924)

四校很丧,但是学长的题目更简单 lrb学长的题目为什么都要倒着切,不懂QAQ ----------------我是分割线---------------- T1:个人卫生综合征 每天BBS都要从家里经过城市中的一段路到学校刷五三.城市中一共有n个路口和m条双向道路,每条双向道路都连接着两个路口ai.bi且有一定的时间花费vi.BBS家编号为1,学校编号为n.今天,BBS由于个人卫生综合征导致他很迟才离开家,他想用膜法改变k条道路的长度使通过其的时间花费vi变为0.现在他问你改变道路长度之后他到学校

校内模拟赛(20170921)

救命啊,救命啊!学长出丧题啦!!! 学长他们压榨我们的劳动力,然后带着我们的成绩跑了,无奈的我们只好玩命的调程序,把学长留给我们的丧题做完(划掉) 65分的rank 1跑路. ----------------我是分割线---------------- T1:粉饰(decorate) [题目描述] 小D有一块被分为n*m个格子的矩形鱼片.为了装饰鱼片,小D决定给每个格子上色.由于小D很喜欢红白,所以小D给每个格子涂上了红色或白色,第i行第j列的格子颜色记为c[i,j].涂完之后,小D想评估这块鱼片