题意

维护一个数据结构,支持两个数列的区间求和,和查询区间内两数列各元素积的和。

分析

线段树万岁!

这道题要维护两个序列,所以线段树中要同时存储两个区间和。但还要在维护一个信息,是该区间内两序列元素积的和。大概长这样:

struct no
{
int l,r;
int da,db,ab;
int ta,tb;
}t[maxn<<2];

其他的更新就不讲了,主要说一说积的和信息的更新。

当更新一个序列时,该信息要传递的信息其实是另一盒序列的和乘上该序列的懒标记,这点很好想。

然后就没有什么问题了。但是注意这道题要取模,你少取一个就废了。

Code

#include<bits/stdc++.h>
//#include<atcoder/modint>
#define int long long
using namespace std;
//using mint=atcoder::modint998244353;
inline int read()
{
int w=1,s=0;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
while(isdigit(ch)){s=s*10+(ch-'0');ch=getchar();}
return w*s;
}
const int maxn=1e6+10;
const int mod=998244353;
struct no
{
int l,r;
int da,db,ab;
int ta,tb;
}t[maxn<<2];
int a[maxn],b[maxn],n,Q;
void upd(int p)
{
t[p].da=(t[p*2].da+t[p*2+1].da)%mod;
t[p].db=(t[p*2].db+t[p*2+1].db)%mod;
t[p].ab=(t[p*2].ab+t[p*2+1].ab)%mod;
}
void build(int p,int l,int r)
{
t[p].l=l,t[p].r=r;
if(l==r)
{
t[p].da=a[l]%mod;t[p].db=b[l]%mod;
t[p].ab=a[l]*b[l]%mod;
return ;
}
int mid=(l+r)>>1;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
upd(p);
}
void spread(int p)
{
if(t[p].ta)
{
t[p*2].da+=t[p].ta*(t[p*2].r-t[p*2].l+1)%mod;t[p*2].da%=mod;
t[p*2+1].da+=t[p].ta*(t[1+p*2].r-t[1+p*2].l+1)%mod;t[p*2+1].da%=mod;
t[p*2].ta+=t[p].ta;t[p*2].ta%=mod;
t[p*2+1].ta+=t[p].ta;t[p*2+1].ta%=mod;
t[p*2].ab+=t[p].ta*t[p*2].db%mod;t[p*2].ab%=mod;
t[p*2+1].ab+=t[p].ta*t[p*2+1].db%mod;t[p*2+1].ab%=mod;
}
if(t[p].tb)
{
t[p*2].db+=t[p].tb*(t[p*2].r-t[p*2].l+1)%mod;t[p*2].db%=mod;
t[p*2+1].db+=t[p].tb*(t[1+p*2].r-t[1+p*2].l+1)%mod;t[p*2+1].db%=mod;
t[p*2].tb+=t[p].tb;t[p*2].tb%=mod;
t[p*2+1].tb+=t[p].tb;t[p*2+1].tb%=mod;
t[p*2].ab+=t[p].tb*t[p*2].da%mod;t[p*2].ab%=mod;
t[p*2+1].ab+=t[p].tb*t[p*2+1].da%mod;t[p*2+1].ab%=mod;
}
t[p].ta=0;
t[p].tb=0;
}
void changea(int p,int l,int r,int k)
{
if(t[p].l>=l&&t[p].r<=r)
{
t[p].da+=k*(t[p].r-t[p].l+1)%mod;t[p].da%=mod;
t[p].ta+=k;t[p].ta%=mod;
t[p].ab+=k*t[p].db%mod;t[p].ab%=mod;
return ;
}
spread(p);
int mid=(t[p].l+t[p].r)>>1;
if(l<=mid)changea(p*2,l,r,k);
if(mid<r) changea(p*2+1,l,r,k);
upd(p);
}
void changeb(int p,int l,int r,int k)
{
if(t[p].l>=l&&t[p].r<=r)
{
t[p].db+=k*(t[p].r-t[p].l+1)%mod;t[p].db%=mod;
t[p].tb+=k;t[p].tb%=mod;
t[p].ab+=k*t[p].da%mod;t[p].ab%=mod;
return ;
}
spread(p);
int mid=(t[p].l+t[p].r)>>1;
if(l<=mid)changeb(p*2,l,r,k);
if(mid<r) changeb(p*2+1,l,r,k);
upd(p);
}
int ask(int p,int l,int r)
{
if(t[p].l>=l&&t[p].r<=r)
{
return t[p].ab%mod;
}
spread(p);
int mid=(t[p].l+t[p].r)>>1,sum=0;
if(l<=mid)sum=(sum+ask(p*2,l,r)%mod)%mod;
if(mid<r) sum=(sum+ask(p*2+1,l,r)%mod)%mod;
return sum%mod;
}
signed main()
{
// freopen("xxx.in","r",stdin);
// freopen("xxx.out","w",stdout);
cin>>n>>Q;
for(int i=1;i<=n;i++)a[i]=read();
for(int i=1;i<=n;i++)b[i]=read();
build(1,1,n);
while(Q--)
{
int opt=read(),l=read(),r=read();
if(opt==3)
{
printf("%lld\n",ask(1,l,r)%mod);
continue;
}
int x=read();
if(opt==1)changea(1,l,r,x);
if(opt==2)changeb(1,l,r,x);
}
return 0;
}

题解:AT_abc357_f [ABC357F] Two Sequence Queries的更多相关文章

  1. 【题解】Cut the Sequence(贪心区间覆盖)

    [题解]Cut the Sequence(贪心区间覆盖) POJ - 3017 题意: 给定一大堆线段,问用这些线段覆盖一个连续区间1-x的最小使用线段的数量. 题解 考虑一个这样的贪心: 先按照左端 ...

  2. 题解 CF1304E 【1-Trees and Queries】

    前言 这场比赛,在最后 \(5\) 分钟,我想到了这道题的 \(Idea\),但是,没有打完,比赛就结束了. 正文 题目意思 这道题目的意思就是说,一棵树上每次给 \(x\) 和 \(y\) 节点连 ...

  3. 【题解】Luogu CF817F MEX Queries

    原题传送门 817,我突然想到了某8位质数 这题珂以说是珂朵莉树的模板 三个操作都肥肠简单,前两个区间赋值,第三个区间0变1,1变0 每次输出从头开始扫描就行(我忘了珂朵莉树的性质,竟然还动态维护最左 ...

  4. 题解 CF375D 【Tree and Queries】

    首先,子树上的查询问题可以通过$DFS$序转为序列问题 再一看,没有修改,可以离线,这不就是莫队吗? 我们用$sum_i$表示出现次数$\geq i$的个数 用$val_i$表示第$i$种颜色的出现次 ...

  5. 题解 UVA1479 【Graph and Queries】

    \[ \text{Preface} \] 算是一道思维难度稍易,代码难度稍难的题吧. \[ \text{Description} \] 给出一张 \(n\) 个点,\(m\) 条边的图,点带权.需要支 ...

  6. 题解 CF938G 【Shortest Path Queries】

    题目让我们维护一个连通无向图,边有边权,支持加边删边和询问从\(x\)到\(y\)的异或最短路. 考虑到有删边这样的撤销操作,那么用线段树分治来实现,用线段树来维护询问的时间轴. 将每一条边的出现时间 ...

  7. 【题解】CF375D Tree and Queries

    Link \(\text{Solution:}\) 讲实话这题有点烦,不知道为啥改了下\(\text{dfs}\)就过了--原版本\(dfs\)好像没啥错啊-- 其实对于子树问题,我们求出原来树的\( ...

  8. 题解 Yet Another Number Sequence

    题目传送门 Description 给出 \(n,k\) ,求出: \[\sum_{i=1}^{n} f_i·i^k \] 其中 \(f_i\) 表示斐波拉契第 \(i\) 项.\(n\le 10^{ ...

  9. Ural 1248 Sequence Sum 题解

    目录 Ural 1248 Sequence Sum 题解 题意 题解 程序 Ural 1248 Sequence Sum 题解 题意 给定\(n\)个用科学计数法表示的实数\((10^{-100}\s ...

  10. 2015 Multi-University Training Contest 1 题解&&总结

    ---------- HDU 5288 OO’s Sequence 题意 给定一个数列(长度<$10^5$),求有多少区间[l,r],且区间内有多少数,满足区间内其它数不是他的约数. 数的范围$ ...

随机推荐

  1. 实战-mongodb副本集搭建以及整合springboot使用

    一 mongodb介绍 MongoDB是一个基于分布式文件存储的数据库.由C++语言编写.旨在为WEB应用提供可扩展的高性能数据存储解决方案.  Nosql 技术门类 redis 内存型 mongod ...

  2. vue2遇到的一些错误

    一.VUE中的VUEX如何调用modules里面的mutations和state   ...mapMutations("workflow",['setApproverConfig' ...

  3. win10找回Ubuntu启动项(非EasyBCD)

    最近想对装在电脑上的Ubuntu进行更新,但是之前在BIOS里改了引导系统的文件,导致找不到Ubuntu启动项,EasyBCD程序也不起作用(整块硬盘Windows分区都是GPT,改BIOS也没什么用 ...

  4. Json.Net Deserialize a Collection from BSON

    Deserialize a Collection from BSON (newtonsoft.com) This sample sets ReadRootValueAsArray to true so ...

  5. 支持表格识别,PaddleOCRSharp最新发布

    PaddleOCRSharp 2.3.0已经发布nuget包. 项目开源地址:https://gitee.com/raoyutian/paddle-ocrsharp 2.3.0更新内容: 1.增加表格 ...

  6. python-使用pyecharts绘制各省份985学校数量图

    1.环境 代码运行环境:python3.7 相关的库:pyecharts 1.7.1 代码编辑器:visual studio code 2.目的 通过使用pyecharts库,来绘制全国各省985高校 ...

  7. 从零开始写 Docker(十七)---容器网络实现(中):为容器插上”网线“

    本文为从零开始写 Docker 系列第十七篇,利用 linux 下的 Veth.Bridge.iptables 等等相关技术,构建容器网络模型,为容器插上"网线". 完整代码见:h ...

  8. JavaScript语法形式1行内式

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. jquery的循环 tab切换

        <ul>         <li>1</li>         <li>2</li>         <li>3< ...

  10. CF1777E

    problem & blog 反转的边最大权值最小,想到二分. 于是二分代价即可. 反转代价小于二分的代价的边可以反转,所以再建一条反向边即可. 在 DAG 中,存在一个点可以到达所有的点的条 ...