题意

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

分析

线段树万岁!

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

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. web component基础概念及使用

    概念和使用 作为开发者,我们都知道尽可能多的重用代码是一个好主意.这对于自定义标记结构来说通常不是那么容易 - 想想复杂的HTML(以及相关的样式和脚本),有时您不得不写代码来呈现自定义UI控件,并且 ...

  2. Python闭包和装饰器原理

    # Python闭包和装饰器 ############# 闭包 ############## ''' 1. 一个外层函数,内嵌一个内层函数: 2. 内层函数使用外层函数的参数: 3. 外层函数将内层函 ...

  3. Django模型层的QuerySet对象

    def index(request): # 查询数据,返回QuerySet对象books books=Book.objects.filter(id__gte=1) # 打印books, 是一个Quer ...

  4. WebView2在WPF中的应用

    开发环境 运行环境:.Net 6 开发环境:Visual Studio 2022 17.1.3 框架语言:WPF 安装WebView2 通过Package Manager控制台安装 Install-P ...

  5. 记一次 .NET某工控WPF程序被人恶搞的 卡死分析

    一:背景 1. 讲故事 这一期程序故障除了做原理分析,还顺带吐槽一下,熟悉我的朋友都知道我分析dump是免费的,但免费不代表可以滥用我的宝贵时间,我不知道有些人故意恶搞卡死是想干嘛,不得而知,希望后面 ...

  6. docker资源限制与数据持久化

    1. docker简介和核心概念 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化.容器是完全使 ...

  7. 【论文笔记】SegNet

    [深度学习]总目录 SegNet是Cambridge提出旨在解决自动驾驶或者智能机器人的图像语义分割深度网络,开放源码,基于caffe框架.SegNet运用编码-解码结构和最大池化索引进行上采样,最主 ...

  8. Vulkan Support Check and Dynamic Loader C++ code sample

    很多时候不想静态依赖VulkanSDK所提供的静态库,因为会遇到一些过早的电脑不支持vulkan, 那么就需要使用动态加载vulkan-1.dll(for Windows)或libMoltenVK.d ...

  9. Ubuntu Server LTS 修改网卡ip地址、固定IP

    Ubuntu Server LTS 修改网卡ip地址方式.固定IP. 18.04 之前版本通过修改/etc/network/interfaces 方式,18.04 版本开始通过netplan 方式: ...

  10. nfs笔记整理

    NFS---共享存储系统 #network file system 网络文件系统 ​ #NFS主要使用在局域网下,让不同的主机之间可以共享文件.或者目录数据.主要用于linux系统上实现文件共享的一种 ...