原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round10-D.html

题目传送门 - https://www.nowcoder.com/acm/contest/148/D

题意

  多组数据。

  给定一个长度为 $n$ 初始全为 $0$ 的数列 $A$ 。$m$ 次操作,要求支持以下三种操作。

  1. 区间加一个数 $v$

  2. 全局修改,对于每一个 $i$ ,把 $A_i$ 改成原序列前 $i$ 项的和。

  3. 区间求和。(询问次数不超过500)

  $n,m\leq 10^5,v\leq 10^9$

题解

  我们首先考虑在位置 $x$ 的一个数 $v$ ,在取 $k$ 次前缀和之后,对位置为 $y$ 的数的贡献为多少?

  令 $L=y-x+1$ ,随便推式子或者打个表都可以得到贡献为:

$$\binom{(k-1)+(L-1)}{k-1}v$$

  预处理组合数。由于询问次数 $\leq 500$ ,我们如果可以 $O(m)$ 回答每一个询问,那么就非常给力了。

  由于区间修改的操作数太多了,所以我们取差分数组(一次反前缀和),在差分数组上做两次单点修改即可完成区间修改。

  同理,区间询问我们不可能把每一个点的答案都算出来,我们取前缀和,于是区间询问就可以拆成两个单点询问,通过差分搞定了。

  至于这个如何实现取前缀和数组,和取反前缀和数组,只需要记录一下当前的前缀和次数 $k$ 。

  遇到操作 2 的时候 k++ 即可。

  遇到操作 1 的时候,把单点修改的操作记下来,需要记录当前修改位置,修改值,当前修改时,取了几次前缀和。

  时间复杂度 $O(mq)$ 。

代码

#include <bits/stdc++.h>
using namespace std;
const int N=200005,mod=998244353;
int read(){
int x=0;
char ch=getchar();
while (!isdigit(ch))
ch=getchar();
while (isdigit(ch))
x=(x<<1)+(x<<3)+ch-48,ch=getchar();
return x;
}
int Pow(int x,int y){
int ans=1;
for (;y;y>>=1,x=1LL*x*x%mod)
if (y&1)
ans=1LL*ans*x%mod;
return ans;
}
int T,n,m;
struct Point{
int x,k,v;
Point(){}
Point(int _x,int _y,int _v){
x=_x,k=_y,v=_v;
}
}o[N];
int ocnt,k;
int Fac[N],Inv[N];
int C(int n,int m){
if (m<0||m>n)
return 0;
return 1LL*Fac[n]*Inv[m]%mod*Inv[n-m]%mod;
}
void add(int &x,int y){
x+=y;
if (x>=mod)
x-=mod;
}
int solve(int x){
k+=2;
int res=0;
for (int i=1;i<=ocnt;i++)
if (o[i].x<x)
res=(1LL*o[i].v*C(k-o[i].k+x-o[i].x-1,k-o[i].k-1)+res)%mod;
else if (o[i].x==x)
add(res,o[i].v);
k-=2;
return res;
}
int main(){
Fac[0]=Inv[0]=1;
for (int i=1;i<N;i++){
Fac[i]=1LL*Fac[i-1]*i%mod;
Inv[i]=Pow(Fac[i],mod-2);
}
scanf("%d",&T);
while (T--){
n=read(),m=read();
ocnt=0,k=-1;
for (int i=1;i<=m;i++){
int opt=read(),L,R,v;
if (opt==2){
k++;
continue;
}
L=read(),R=read();
if (opt==1){
v=read();
o[++ocnt]=Point(L,k,v);
o[++ocnt]=Point(R+1,k,(mod-v)%mod);
}
if (opt==3)
printf("%d\n",(solve(R)-solve(L-1)+mod)%mod);
}
}
return 0;
}

  

2018牛客网暑假ACM多校训练赛(第十场)D Rikka with Prefix Sum 组合数学的更多相关文章

  1. 2018牛客网暑假ACM多校训练赛(第二场)E tree 动态规划

    原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round2-E.html 题目传送门 - 2018牛客多校赛第二场 E ...

  2. 2018牛客网暑假ACM多校训练赛(第三场)I Expected Size of Random Convex Hull 计算几何,凸包,其他

    原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round3-I.html 题目传送门 - 2018牛客多校赛第三场 I ...

  3. 2018牛客网暑假ACM多校训练赛(第三场)G Coloring Tree 计数,bfs

    原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round3-G.html 题目传送门 - 2018牛客多校赛第三场 G ...

  4. 2018牛客网暑假ACM多校训练赛(第三场)D Encrypted String Matching 多项式 FFT

    原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round3-D.html 题目传送门 - 2018牛客多校赛第三场 D ...

  5. 2018牛客网暑假ACM多校训练赛(第十场)H Rikka with Ants 类欧几里德算法

    原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round10-H.html 题目传送门 - https://www.n ...

  6. 2018牛客网暑假ACM多校训练赛(第十场)F Rikka with Line Graph 最短路 Floyd

    原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round10-F.html 题目传送门 - https://www.n ...

  7. 2018牛客网暑假ACM多校训练赛(第八场)H Playing games 博弈 FWT

    原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round8-H.html 题目传送门 - https://www.no ...

  8. 2018牛客网暑假ACM多校训练赛(第七场)I Tree Subset Diameter 动态规划 长链剖分 线段树

    原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round7-I.html 题目传送门 -  https://www.n ...

  9. 2018牛客网暑假ACM多校训练赛(第六场)I Team Rocket 线段树

    原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round6-I.html 题目传送门 - https://www.no ...

随机推荐

  1. 【原创】数据库基础之Mysql(3)mysql删除历史binlog

    mysql开启binlog后会在/var/lib/mysql下创建binlog文件,如果手工删除,则下次mysql启动会报错: mysqld: File './master-bin.000001' n ...

  2. winfrom里面打印类似小票

    首先在窗体上拖一个printDocument1控件和一个Button按钮,然后双击该控件的PrintPage事件,在事件里面复制下面代码: Pen blackPen = new Pen(Color.B ...

  3. python-常用模块xml、shelve、configparser、hashlib

    一.shelve模块 shelve模块也是用来序列化的. 使用方法: 1.open 2.读写 3.close import shelve # 序列化 sl = shelve.open('shlvete ...

  4. Linux文件系统深度讨论【转】

      本文旨在对Linux文件系统概念高级工作方式进行的讨论,不是对特定文件系统类型(如EXT4)如何工作的低级描述,也不是对文件系统命令的教程. 每台通用计算机都需要将各种类型的数据存储在硬盘驱动器( ...

  5. jenkins 安装网址

    https://wiki.jenkins.io/display/JENKINS/Installing+Jenkins

  6. Confluence 6 临时目录(安装目录)

    temp 目录是由 Java 运行时进行配置的,同时一些 Confluence 的组件将会写入历史文件或者锁定文件到这个目录中. 临时目录位于安装目录下的 /temp 目录中. 希望修改这个目录的位置 ...

  7. Confluence 6 从你的 JDBC 连接中直接启用校验查询

    确定 Confluence 在数据库连接池中校验数据库连接: 停止 Confluence. 编辑 <home-directory>confluence.cfg.xml 文件. 针对你特定的 ...

  8. 【Linux】添加DNS

    1.添加DNS输入命令: vi /etc/resolv.conf 添加一行:nameserver 10.41.132.9 2.查看DNS nslookup 127.0.0.1 | grep Serve ...

  9. 【gearman】gearmand -d 无反应解决

    背景:安装了gearman后,用指令gearmand -d启动后.输入ps -ef|grep gearmand 查找不到.说明服务并没有启动. 查看报错: gearmand -d -l gear.lo ...

  10. Python基础之递归函数与二分法

    一.递归函数 定义: 在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数. 我们来举个例子吧,比如:有个人问“egon”年龄,他说比“小大”大5岁,“小大”又说比“小保 ...