传送门

差了一点没想到正解……

首先单次询问的 \(O(n)\) 写法很好想,考虑如何优化

首先基础分区间求和即可

然后那个连击分的话,是一个关于 \(f_i\) 和 \(f_{i-1}\) 的柿子

\[f_i = p*(f_{i-1}+1)+(1-p)*f_{i-1}*t
\]

移个项

\[f_i = (p+t-p*t)f_{i-1}+p
\]

就表示成了一个 \(f_i = k_i*f_{i-1}+b_i\) 的形式

  • 形似 \(f_i = k_i*f_{i-1}+b_i\) 的柿子可以用线段树维护,核心在于维护出每个区间 \(R\) 位置相对 \(L-1\) 位置的 \(k\) 和 \(b\)

于是发现我们要求的 \(\sum p_i(f_{i-1}+1)\) 本来就是一个 \(kx+b\) 的形式

直接维护就好了

Code:
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 500010
#define ll long long
#define reg register int
//#define int long long char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
int ans=0, f=1; char c=getchar();
while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
return ans*f;
} int n, q, sub;
int ta, tb, A, B, t, pa, pb;
int p[N], c[N];
const ll mod=998244353;
const int mod2=998244353;
inline void md(int& a, ll b) {a+=b; a=a>=mod2?a-mod2:a;}
inline int md(int a) {return a>=mod2?a-mod2:a;}
struct equ{int k, b, sumk, sumb; equ(){} equ(int e, int f, int g, int h):k(e),b(f),sumk(g),sumb(h){}};
inline equ operator + (equ a, equ b) {
equ ans;
ans.k=1ll*a.k*b.k%mod;
ans.b=(1ll*b.k*a.b+b.b)%mod;
ans.sumk=(a.sumk+1ll*b.sumk*a.k)%mod;
ans.sumb=(a.sumb+1ll*b.sumk*a.b+b.sumb)%mod;
return ans;
}
int tl[N<<2], tr[N<<2], sum[N<<2]; equ sk[N<<2];
#define tl(p) tl[p]
#define tr(p) tr[p]
#define sum(p) sum[p]
#define sk(p) sk[p]
#define k(p) sk[p].k
#define b(p) sk[p].b
#define sumk(p) sk[p].sumk
#define sumb(p) sk[p].sumb
inline void pushup(int p) {
sum(p)=md(sum(p<<1)+sum(p<<1|1));
sk(p)=sk(p<<1)+sk(p<<1|1);
}
void build(int tp, int l, int r) {
tl(tp)=l; tr(tp)=r;
if (l==r) {sum(tp)=p[l]; k(tp)=(p[l]+t-1ll*p[l]*t)%mod; b(tp)=sumk(tp)=sumb(tp)=p[l]; return ;}
int mid=(tl(tp)+tr(tp))>>1;
build(tp<<1, l, mid);
build(tp<<1|1, mid+1, r);
pushup(tp);
}
void upd(int p, int pos, int dat) {
if (tl(p)==tr(p)) {sum(p)=dat; k(p)=(dat+t-1ll*dat*t)%mod; b(p)=sumk(p)=sumb(p)=dat; return ;}
int mid=(tl(p)+tr(p))>>1;
if (pos<=mid) upd(p<<1, pos, dat);
else upd(p<<1|1, pos, dat);
pushup(p);
}
int queryA(int p, int l, int r) {
if (l<=tl(p) && r>=tr(p)) return sum(p);
int mid=(tl(p)+tr(p))>>1, ans=0;
if (l<=mid) md(ans, queryA(p<<1, l, r));
if (r>mid) md(ans, queryA(p<<1|1, l, r));
return ans;
}
equ query(int p, int l, int r) {
if (l<=tl(p) && r>=tr(p)) return sk(p);
int mid=(tl(p)+tr(p))>>1;
if (l<=mid && r>mid) return query(p<<1, l, r)+query(p<<1|1, l, r);
if (l<=mid) return query(p<<1, l, r);
if (r>mid) return query(p<<1|1, l, r);
puts("error");
return sk(p);
}
int queryA(int l, int r) {
int tem=1ll*A*queryA(1, l, r)%mod;
return md(tem+mod);
} ll qpow(ll a, ll b) {
ll ans=1;
while (b) {
if (b&1) ans=ans*a%mod;
a=a*a%mod; b>>=1;
}
return ans;
} #if 0
namespace force{
ll query(int l, int r) {
ll base=0, com=0;
for (int i=l; i<=r; ++i) md(base, p[i]);
base=base*A%mod;
c[l]=p[l]; md(com, p[l]%mod);
for (int i=l+1; i<=r; ++i) {
c[i]=(p[i]*(c[i-1]+1)%mod + (1-p[i])*c[i-1]%mod*t%mod)%mod;
c[i]=(c[i]%mod+mod)%mod;
md(com, p[i]*(c[i-1]+1)%mod);
}
ll tem=(base+com*B%mod)%mod;
//assert(tem>=0);
return (tem+mod)%mod;
}
void solve() {
for (int i=1,op,l,r,x; i<=q; ++i) {
op=read();
if (op&1) {
l=read(); r=read();
printf("%lld\n", query(l, r));
}
else {
x=read(); pa=read(); pb=read();
p[x]=pa*qpow(pb, mod-2)%mod;
}
}
exit(0);
}
} namespace task1{
void solve() {
build(1, 1, n);
for (int i=1; i<=n; ++i) upd(1, i, p[i]);
for (int i=1,op,l,r,x; i<=q; ++i) {
op=read();
if (op&1) {
l=read(); r=read();
printf("%lld\n", queryA(l, r));
}
else {
x=read(); pa=read(); pb=read();
p[x]=pa*qpow(pb, mod-2)%mod;
upd(1, x, p[x]);
}
}
exit(0);
}
}
#endif namespace task{
void solve() {
build(1, 1, n);
equ tem;
for (reg i=1,op,l,r,x; i<=q; ++i) {
op=read();
if (op&1) {
l=read(); r=read();
//cout<<"op=1"<<endl;
if (l==r) printf("%lld\n", (p[l]*A+p[l]*B)%mod);
else {
tem=query(1, l+1, r);
ll ans=(1ll*p[l]*tem.sumk+tem.sumb+p[l])%mod*B+queryA(l, r);
ans = md(ans%mod+mod);
printf("%lld\n", ans);
}
}
else {
x=read(); pa=read(); pb=read();
p[x]=pa*qpow(pb, mod-2)%mod;
upd(1, x, p[x]);
}
}
exit(0);
}
} signed main()
{
sub=read();
n=read(); q=read(); ta=read(); tb=read(); A=read(); B=read();
if (!q) return 0;
t=ta*qpow(tb, mod-2)%mod;
for (reg i=1; i<=n; ++i) {
pa=read(); pb=read();
p[i]=pa*qpow(pb, mod-2)%mod;
}
//if (!B) task1::solve();
//else force::solve();
task::solve(); return 0;
}

题解 Omeed的更多相关文章

  1. 20210824 Prime,Sequence,Omeed

    考场 T1 貌似是 luogu 上原题 T2 计数,想起了这题和这题,但没有 \(n^2\) 一档的分...准备打个表 T3 期望 DP,但暴力是 \(O(qn)\) 的,发现 \(combo\) 的 ...

  2. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  3. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  4. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  5. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  6. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  7. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  8. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  9. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

随机推荐

  1. CF1539C Stable Groups[题解]

    Stable Groups 题目大意 给定 \(n\) 个数 \(a_i\) ,你可以将这些数分成若干组,但每一组的元素满足按升序排列后,相邻两个元素值的差不超过 \(x\) .在分组前,你可以向这些 ...

  2. Red Hat系统下安装gcc

    这篇是在客户服务器上安装redis碰到的问题.服务器是RedHat,无法直接安装gcc,导致Redis无法安装的解决办法:    1.make redis时候报下面这样的错,原因就是gcc没有安装. ...

  3. sqliab刷题笔记-联合注入

    Less-1 测试是字符型还是数字型 判断所在字段数 查看显示值 可以看出显示2,3位置.因此我们选择2的位置进行联合注入 查看表名 我们要对admin,users等字符敏感 查看admin表中的字段 ...

  4. Scrapy 爬虫框架学习笔记(未完,持续更新)

    Scrapy 爬虫框架 Scrapy 是一个用 Python 写的 Crawler Framework .它使用 Twisted 这个异步网络库来处理网络通信. Scrapy 框架的主要架构 根据它官 ...

  5. 如何使用odoo的compute方法,自动计算odoo字段

    前言 在odoo的ORM创建数据字段的过程中,我们会经常需要定义一些字段用来计算某一些字段只和或其他计算结果. 今天介绍一个很好用的方法compute计算属性,这个方法其实是属于写在odoo fiel ...

  6. 基于小熊派Hi3861鸿蒙开发的IoT物联网学习【三】

    软件定时器:是基于系统Tick时钟中断且由软件来模拟的定时器,当经过设定的Tick时钟计数值后会触发用户定义的回调函数.定时精度与系统Tick时钟的周期有关. 定时器运行机制: cmsis_os2的A ...

  7. 第十四篇 -- CPU学习二——此部分重点在AMD CPU

    一.CPU的一些英文简写或解释 Definitions: ACPI--Advanced Configuration and Power Interface APP--Adjusted Peak Per ...

  8. Redis内部阻塞式操作有哪些?

    Redis实例在运行的时候,要和许多对象进行交互,这些不同的交互对象会有不同的操作.下面我们来看看,这些不同的交互对象以及相应的主要操作有哪些. 客户端:键值对的增删改查操作. 磁盘:生成RDB快照. ...

  9. Python脚本:爬取天气数据并发邮件给心爱的Ta

    第一部分:爬取天气数据 # 在函数调用 get_weather(url = 'https://www.tianqi.com/foshan') 的 url中更改城市,foshan为佛山市 1 impor ...

  10. Python爬虫+可视化教学:爬取分析宠物猫咪交易数据

    前言 各位,七夕快到了,想好要送什么礼物了吗? 昨天有朋友私信我,问我能用Python分析下网上小猫咪的数据,是想要送一只给女朋友,当做礼物. Python从零基础入门到实战系统教程.源码.视频 网上 ...