先摆出来这个式子

\[score=A\sum S_i+B\sum S_i\times f(i)
\]

先研究\(f\)函数(也就是Combo函数)

显然的有

\[f(i)=P_i(f(i-1)+1)+t(1-P_i)f(i-1)
\]

化简得

\[f(i)=(P_i+t-tP_i)f(i-1)+P_i
\]

再考虑一下期望意义下的式子

\[score=A\sum P_i+B\sum P_i\times f(i)
\]

然而,这是不对的,第一个样例都过不了

问题出在哪?就在\(P_i\times f(i)\)这里

\(P_i\)意味着第i位必为1,此时的\(f(i)\)应当在(2)式中将\(P_i\)代为1,也就是此时

\[score=A\sum P+B\sum P_i\times(f(i-1)+1)
\]

到这里,第一部分就是一个区间和,第二部分考场上直接写暴力了

现在考虑一下如何快速维护第二个信息

\[cost(i,j)=\sum\limits_{k=i}^jP_k\times (f(k-1)+1)=\sum\limits_{k=i}^jP_kf(k-1)+P_k
\]

和式里面是一个一次函数的形式,自变量是\(f(x)\),根据(3)式,\(f(x)\)也是一个一次函数的形式

这就可以用线段树维护了,单点修改很好实现,考虑\(P_i+d\)中\(d\)的贡献即可

对于一个区间\([L,R]\),记录\(k_1,b_1,k_2,b_2\)表示\(f(R)=k_1f(L-1)+b_1,cost(L,R)=k_2f(L-1)+b_2\)

由于它们都是一次函数,所以一定可以这样表出

现在考虑如何合并区间信息,考虑边界情况,对于一个区间\([i,i]\),根据(3)和(6)有

\(k_1=P_i+t-tP_i ,\ b1=P_i,\ k_2=P_i,\ b_2=P_i\)

考虑一个区间\([L,R]\),中点为\(m\)

\[\begin{align*}
f(m)&=k_1f(L-1)+b_1\\
f(R)&=k_1'f(m)+b_1'\\
\therefore f(R)&=k_1k_1'f(L-1)+k_1'b_1+b_2\\
cost(L,m)&=k_2f(L-1)+b_2\\
cost(m+1,R)&=k_2'f(m)+b_2'\\
\therefore cost(L,R)&=(k_2+k_2'k_1)f(L-1)+b_2+b_2'+k_2'b_1
\end{align*}
\]

这样就能合并区间了,由于\(f(L-1)=0\),所以答案区间\([L,R]\)的答案就是

\[score[L,R]=A\sum_{i=L}^RP_i+B\times b_2
\]

只维护\(f\)是不能做的,考场上并没有想到再维护一个\(cost\),参考了杨神犇的博客

线段树真是处理区间可合并信息的利器

#include<algorithm>
#include<iostream>
#include<cstdio> using namespace std; inline char gc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int rd(){
int ret=0,f=1;char c;
while(c=gc(),!isdigit(c))f=c=='-'?-1:1;
while(isdigit(c))ret=ret*10+c-'0',c=gc();
return ret*f;
}
#define space() putchar(' ')
#define nextline() putchar('\n')
void pot(int x){if(!x)return;pot(x/10);putchar('0'+x%10);}
void out(int x){if(!x)putchar('0');if(x<0)putchar('-'),x=-x;pot(x);} const int MAXN = 500005;
const int MOD = 998244353; int mul(int x,int y){return (1ll*x*y)%MOD;}
void Mul(int &x,int y){x=mul(x,y);}
int sub(int x,int y){return x-y<0?x-y+MOD:x-y;}
int add(int x,int y){if(y>=0)return x+y>MOD?x+y-MOD:x+y;else return sub(x,-y);}
void Add(int &x,int y){x=add(x,y);} inline int qpow(int x,int y){
int ret=1;
while(y){
if(y&1)Mul(ret,x);
Mul(x,x);
y>>=1;
}
return ret;
}
inline int inv(int x){return qpow(x,MOD-2);} int n,q,t,dt,ta,tb,A,B;
int p[MAXN]; #define ls (cur<<1)
#define rs (cur<<1|1)
#define mid ((l+r)>>1)
struct Node{
int k1,k2,b1,b2;
Node(int x=1,int y=0,int u=1,int v=0){k1=x;b1=y;k2=u;b2=v;}
}node[MAXN<<2];
inline Node merge(const Node &x,const Node &y){
return Node(
mul(x.k1,y.k1),
add(mul(x.b1,y.k1),y.b1),
add(x.k2,mul(y.k2,x.k1)),
add(mul(y.k2,x.b1),add(x.b2,y.b2))
);
}
void build(int L,int R,int cur,int l,int r){
if(l==r){
node[cur]=Node(sub(add(p[l],t),mul(t,p[l])),p[l],p[l],p[l]);
return;
}
if(L<=mid)build(L,R,ls,l,mid);
if(mid <R)build(L,R,rs,mid+1,r);
node[cur]=merge(node[ls],node[rs]);
}
void update(int pos,int cur,int l,int r,int w){//add w
if(l==r){
Add(node[cur].k1,mul(dt,w));
Add(node[cur].b1,w);
Add(node[cur].k2,w);
Add(node[cur].b2,w);
return;
}
if(pos<=mid) update(pos,ls,l,mid,w);
else update(pos,rs,mid+1,r,w);
node[cur]=merge(node[ls],node[rs]);
}
Node query(int L,int R,int cur,int l,int r){
if(L<=l&&r<=R) return node[cur];
if(L<=mid&&(!(mid<R)))return query(L,R,ls,l,mid);
if((!(L<=mid))&&(mid<R))return query(L,R,rs,mid+1,r);
return merge(query(L,R,ls,l,mid),query(L,R,rs,mid+1,r));
}
struct BIT{
int b[MAXN];
void update(int x,int w){
for(int i=x;i<=n;i+=i&-i)Add(b[i],w);
}
int query(int x){
int ret=0;
for(int i=x;i;i-=i&-i)Add(ret,b[i]);
return ret;
}
}bit; void answer(){
int l,r;
l=rd();r=rd();
int ans=0;
Add(ans,mul(A,add(bit.query(r),-bit.query(l-1))));
Add(ans,mul(B,query(l,r,1,1,n).b2));
out(ans);nextline();
}
void change(){
int pos,wa,wb,w;
pos=rd();wa=rd();wb=rd();
w=mul(wa,inv(wb));
bit.update(pos,-p[pos]);
bit.update(pos,w);
update(pos,1,1,n,-p[pos]);
update(pos,1,1,n,w);
p[pos]=w;
}
int main(){
freopen("omeed.in","r",stdin);
freopen("omeed.out","w",stdout);
rd();
n=rd();q=rd();ta=rd();tb=rd();A=rd();B=rd();
t=mul(ta,inv(tb));
dt=add(1,-t);
int x,y;
for(int i=1;i<=n;i++){
x=rd();y=rd();
p[i]=mul(x,inv(y));
bit.update(i,p[i]);
}
build(1,n,1,1,n);
for(int i=1;i<=q;i++){
x=rd();
if(x==1) answer();
else change();
}
}

[JZOJ] 5837.Omeed的更多相关文章

  1. (jzoj snow的追寻)线段树维护树的直径

    jzoj snow的追寻 DFS序上搞 合并暴力和,记录最长链和当前最远点,距离跑LCA # include <stdio.h> # include <stdlib.h> # ...

  2. [jzoj]3506.【NOIP2013模拟11.4A组】善良的精灵(fairy)(深度优先生成树)

    Link https://jzoj.net/senior/#main/show/3506 Description 从前有一个善良的精灵. 一天,一个年轻人B找到她并请他预言他的未来.这个精灵透过他的水 ...

  3. [jzoj]3468.【NOIP2013模拟联考7】OSU!(osu)

    Link https://jzoj.net/senior/#main/show/3468 Description osu 是一款群众喜闻乐见的休闲软件. 我们可以把osu的规则简化与改编成以下的样子: ...

  4. [jzoj]5478.【NOIP2017提高组正式赛】列队

    Link https://jzoj.net/senior/#main/show/5478 Description Sylvia 是一个热爱学习的女孩子.       前段时间,Sylvia 参加了学校 ...

  5. [jzoj]1115.【HNOI2008】GT考试

    Link https://jzoj.net/senior/#main/show/1115 Description 申准备报名参加GT考试,准考证号为n位数X1X2X3...Xn-1Xn(0<=X ...

  6. [jzoj]2538.【NOIP2009TG】Hankson 的趣味题

    Link https://jzoj.net/senior/#main/show/2538 Description Hanks 博士是BT (Bio-Tech,生物技术) 领域的知名专家,他的儿子名叫H ...

  7. [jzoj]4216.【NOIP2015模拟9.12】平方和

    Link https://jzoj.net/senior/#main/show/4216 Description 给出一个N个整数构成的序列,有M次操作,每次操作有一下三种: ①Insert Y X, ...

  8. [jzoj]2938.【NOIP2012模拟8.9】分割田地

    Link https://jzoj.net/senior/#main/show/2938 Description 地主某君有一块由2×n个栅格组成的土地,有k个儿子,现在地主快要终老了,要把这些土地分 ...

  9. [jzoj]2505.【NOIP2011模拟7.29】藤原妹红

    Link https://jzoj.net/senior/#main/show/2505 Description 在幻想乡,藤原妹红是拥有不老不死能力的人类.虽然不喜欢与人们交流,妹红仍然保护着误入迷 ...

随机推荐

  1. 《SQL 进阶教程》 case:将已有编号方式转换为新的方式并统计

    SQL 权威指南SQL 解惑在进行非定制化统计时,需要将已有编号方式转换为另外一种便于分析的方式进行统计需求 select case when name='哈尔滨' then '黑龙江' when n ...

  2. 4.高级数据过滤 ---SQL

    一.AND操作符 要通过不止一个列进行过滤,可以使用A ND操作符给WHERE子句附加条件. SELECT prod_id, prod_price, prod_name FROM Products ; ...

  3. Django之分页升级版

    如果查询出的数据,被分页了,这个时候翻页的时候应该讲页数的参数和查询的参数一块在URL上显示 """ 分页器 """ from django ...

  4. hdu1175-连连看(dfs)

    一个一个走,记录方向改变了几次,不能超过两次,两次如果还没到终点return: #include<cstdio> #include<string.h> #define inf ...

  5. C. An impassioned circulation of affection DP

    http://codeforces.com/contest/814/problem/C 12ooyomioomioo21 o2 o 这题我是用dp解的,不过好像很慢,比赛的时候算了下不会mle,就没滚 ...

  6. Spark Mllib里如何对决策树二元分类和决策树多元分类的分类数目numClasses控制(图文详解)

    不多说,直接上干货! 决策树二元分类的分类数目numClasses控制 具体,见 Hadoop+Spark大数据巨量分析与机器学习整合开发实战的第13章 使用决策树二元分类算法来预测分类Stumble ...

  7. (译)Minimal Shader(最小的着色器)

    (原文:https://en.wikibooks.org/wiki/Cg_Programming/Unity/Minimal_Shader) This tutorial covers the basi ...

  8. css设置文字超出部分显示省略号。。。

    兼容IE/Firefox/Chrome display:block; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;

  9. Java基础语法(Eclipse)

    Java基础语法 今日内容介绍 u Eclipse开发工具 u 超市库存管理系统 第1章 Eclipse开发工具 Eclipse是功能强大Java集成开发工具.它可以极大地提升我们的开发效率.可以自动 ...

  10. 打印机 Microsoft Print to PDF 所需的驱动程序 Microsoft Print To PDF 未知。登录之前,请与管理员联系,安装驱动程序。

    这个问题发生后,我觉得很疑惑,因为服务器上确定没有安装打印机.那么打印机是从哪里来的呢? 通过百度搜索,发现网上的一个帖子解答了我的疑惑.原帖地址:http://blog.chinaunix.net/ ...