洛谷——P3373 【模板】线段树 2&& B 数据结构
P3373 【模板】线段树 2
题目描述
如题,已知一个数列,你需要进行下面三种操作:
1.将某区间每一个数乘上x
2.将某区间每一个数加上x
3.求出某区间每一个数的和
线段树维护区间乘法
1.如何修改?
一个数去乘区间里的每一个数,那么这个区间的和会乘以这个数,需要乘法标记,初始化为1,乘法标记要乘以这个数,来下传到他的子树中,即更新他的子区间,当然,他的加法标记也要乘以这个数。
2.如何更新?
他子树的值=它的乘法标记*它子树的值+他子树的区间长度*它的加法标记
乘法标记更新,加法标记更新
某位大佬的线段树
#include<bits/stdc++.h>
#define N 4000000
#define LL long long
#define RE register
#define IN inline using namespace std; IN void in(LL &x){
RE char c=getchar();x=;int f=;
while(!isdigit(c)) {if(c=='-') f=-;c=getchar();}
while(isdigit(c)){x=x*+c-'';c=getchar();}
x*=f;
} /*
1.将某区间每一个数乘上x 2.将某区间每一个数加上x 3.求出某区间每一个数的和
*/ LL n,m,X,ans,p;
struct node{
LL l,r,w,f,mul;
}e[N]; IN void build(LL k,LL l,LL r){
e[k].l=l;e[k].r=r;e[k].mul=;e[k].f=;
if(l==r){
in(e[k].w);return;
}LL mid=(l+r)/;
build(k*,l,mid);build(k*+,mid+,r);
e[k].w=(e[k*].w+e[k*+].w)%p;
} IN void down(LL k){
LL mu=e[k].mul,ll=e[k].l,rr=e[k].r,mid=(ll+rr)/;
e[k*].w=(e[k*].w*mu+e[k].f*(mid-ll+))%p;
e[k*+].w=(e[k*+].w*mu+e[k].f*(rr-mid))%p; e[k*].mul=(e[k*].mul*mu)%p;
e[k*+].mul=(e[k*+].mul*mu)%p; e[k*].f=(e[k*].f*mu+e[k].f)%p;
e[k*+].f=(e[k*+].f*mu+e[k].f)%p; e[k].f=;e[k].mul=;
} IN void mull(LL k,LL l,LL r){
LL ll=e[k].l,rr=e[k].r,mid=(ll+rr)/;
if(ll>=l&&rr<=r){
e[k].w=(e[k].w*X)%p;
e[k].mul=(e[k].mul*X)%p;
e[k].f=(e[k].f*X)%p;
return ;
}if(e[k].f!=||e[k].mul!=) down(k);
if(l<=mid) mull(k*,l,r);if(r>mid) mull(k*+,l,r);
e[k].w=(e[k*].w+e[k*+].w)%p;
} IN void change_LLerval(LL k,LL l,LL r){
LL ll=e[k].l,rr=e[k].r,mid=(ll+rr)/;
if(ll>=l&&rr<=r){
e[k].f=(e[k].f+X)%p;
e[k].w=((rr-ll+)*X+e[k].w)%p;return ;
}if(e[k].f!=||e[k].mul!=) down(k);
if(l<=mid) change_LLerval(k*,l,r);if(r>mid) change_LLerval(k*+,l,r);
e[k].w=(e[k*].w+e[k*+].w)%p;
} IN void ask_LLerval(LL k,LL l,LL r){
LL ll=e[k].l,rr=e[k].r,mid=(ll+rr)/;
if(ll>=l&&rr<=r){
ans=(e[k].w+ans)%p;return;
}if(e[k].f!=||e[k].mul!=) down(k);
if(l<=mid) ask_LLerval(k*,l,r);if(r>mid) ask_LLerval(k*+,l,r);
e[k].w=(e[k*].w+e[k*+].w)%p;
} int main()
{
in(n);in(m);in(p);
build(,,n);
while(m--){
LL tp,x,y,k;
in(tp);in(x);in(y);
if(tp!=) in(k);
if(tp==) X=k,mull(,x,y);
else if(tp==) X=k,change_LLerval(,x,y);
else{
ans=,ask_LLerval(,x,y);
printf("%d\n",ans);
}
}return ;
}
B数据结构
链接:https://www.nowcoder.com/acm/contest/200/B
来源:牛客网
qn姐姐最好了~
qn姐姐给你了一个长度为n的序列还有m次操作让你玩,
1 l r 询问区间[l,r]内的元素和
2 l r 询问区间[l,r]内的元素的平方 和
3 l r x 将区间[l,r]内的每一个元素都乘上x
4 l r x 将区间[l,r]内的每一个元素都加上x
维护区间平方和的值。其他类似吧。。
#include<bits/stdc++.h> #define N int(1e6)
#define LL long long using namespace std; void in(LL &x) {
register char c=getchar();
x=;
int f=;
while(!isdigit(c)) {
if(c=='-') f=-;
c=getchar();
}
while(isdigit(c)) {
x=x*+c-'';
c=getchar();
}
x*=f;
} struct node{
LL l,r,w1,w2,mul,ad;
}tr[N]; inline void push_up(int k){
tr[k].w1=tr[k<<].w1+tr[k<<|].w1;
tr[k].w2=tr[k<<].w2+tr[k<<|].w2;
} inline void build(LL k,LL l,LL r){
tr[k].l=l,tr[k].r=r,tr[k].mul=;
if(l==r) {
in(tr[k].w1);
tr[k].w2=tr[k].w1*tr[k].w1;
return;
}
LL mid=(l+r)>>;
build(k<<,l,mid);
build(k<<|,mid+,r);
push_up(k);
} inline void push_down(LL k){
tr[k<<].w2=tr[k<<].w2*tr[k].mul*tr[k].mul+tr[k<<].w1**tr[k].ad+(tr[k<<].r-tr[k<<].l+)*tr[k].ad*tr[k].ad;
tr[k<<].w1=tr[k<<].w1*tr[k].mul+tr[k].ad*(tr[k<<].r-tr[k<<].l+);
tr[k<<].ad+=tr[k].ad;
tr[k<<].mul*=tr[k].mul; tr[k<<|].w2=tr[k<<|].w2*tr[k].mul*tr[k].mul+tr[k<<|].w1**tr[k].ad+(tr[k<<|].r-tr[k<<|].l+)*tr[k].ad*tr[k].ad;
tr[k<<|].w1=tr[k<<|].w1*tr[k].mul+tr[k].ad*(tr[k<<|].r-tr[k<<|].l+);
tr[k<<|].ad+=tr[k].ad;
tr[k<<|].mul*=tr[k].mul; tr[k].ad=,tr[k].mul=;
} inline void update_mul(LL k,LL L,LL R,LL w){
int l=tr[k].l,r=tr[k].r,mid=(l+r)>>;
if(l>=L&&r<=R){
tr[k].mul*=w;
tr[k].ad*=w;
tr[k].w2=w*w*tr[k].w2;
tr[k].w1=w*tr[k].w1;
return;
}
push_down(k);
if(L<=mid) update_mul(k<<,L,R,w);
if(R>mid) update_mul(k<<|,L,R,w);
push_up(k);
} inline void update(LL k,LL L,LL R,LL w){
int l=tr[k].l,r=tr[k].r,mid=(l+r)>>;
if(l>=L&&r<=R){
tr[k].w2+=tr[k].w1**w+(r-l+)*w*w;
tr[k].w1+=w*(r-l+);
tr[k].ad+=w;
return;
}
push_down(k);
if(L<=mid) update(k<<,L,R,w);
if(R>mid) update(k<<|,L,R,w);
push_up(k);
} LL query1(LL k,LL L,LL R){
int l=tr[k].l,r=tr[k].r,mid=(l+r)>>;
if(l>=L&&r<=R) return tr[k].w1;
push_down(k);
LL an=;
if(L<=mid) an+=query1(k<<,L,R);
if(R>mid) an+=query1(k<<|,L,R);
push_up(k);
return an;
} LL query2(LL k,LL L,LL R){
int l=tr[k].l,r=tr[k].r,mid=(l+r)>>;
if(l>=L&&r<=R) return tr[k].w2;
push_down(k);
LL an=;
if(L<=mid) an+=query2(k<<,L,R);
if(R>mid) an+=query2(k<<|,L,R);
push_up(k);
return an;
} LL n,m; int main()
{
in(n),in(m);
build(,,n);
for(LL opt,l,r,w,i=;i<=m;i++){
in(opt),in(l),in(r);
if(opt==){
printf("%lld\n",query1(,l,r));
}
if(opt==){
printf("%lld\n",query2(,l,r));
}
if(opt==){
in(w);
update_mul(,l,r,w);
}
if(opt==){
in(w);
update(,l,r,w);
}
}
return ;
}
洛谷——P3373 【模板】线段树 2&& B 数据结构的更多相关文章
- 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)
To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...
- 线段树_区间加乘(洛谷P3373模板)
题目描述 如题,已知一个数列,你需要进行下面三种操作: 1.将某区间每一个数乘上x 2.将某区间每一个数加上x 3.求出某区间每一个数的和 输入格式: 第一行包含三个整数N.M.P,分别表示该数列数字 ...
- 洛谷 - P1198 - 最大数 - 线段树
https://www.luogu.org/problemnew/show/P1198 要问区间最大值,肯定是要用线段树的,不能用树状数组.(因为没有逆元?但是题目求的是最后一段,可以改成类似前缀和啊 ...
- 洛谷 P2391 白雪皑皑 线段树+优化
题目描述: 现在有 \(N\) 片雪花排成一列. Pty 要对雪花进行$ M $次染色操作,第 \(i\)次染色操作中,把\((i*p+q)%N+1\) 片雪花和第\((i*q+p)%N+1\)片雪花 ...
- 【洛谷】【线段树】P1471 方差
[题目背景:] 滚粗了的HansBug在收拾旧数学书,然而他发现了什么奇妙的东西. [题目描述:] 蒟蒻HansBug在一本数学书里面发现了一个神奇的数列,包含N个实数.他想算算这个数列的平均数和方差 ...
- 【洛谷】【线段树】P1047 校门外的树
[题目描述:] 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0,1,2,……,L ...
- 【洛谷】【线段树】P1886 滑动窗口
[题目描述:] 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. [输入格式:] 输入一共 ...
- 【洛谷】【线段树】P3353 在你窗外闪耀的星星
[题目描述:] /* 飞逝的的时光不会模糊我对你的记忆.难以相信从我第一次见到你以来已经过去了3年.我仍然还生动地记得,3年前,在美丽的集美中学,从我看到你微笑着走出教室,你将头向后仰,柔和的晚霞照耀 ...
- 洛谷P5280 [ZJOI2019]线段树
https://www.luogu.org/problemnew/show/P5280 省选的时候后一半时间开这题,想了接近两个小时的各种假做法,之后想的做法已经接近正解了,但是有一些细节问题理不 ...
- 洛谷P3374(线段树)(询问区间和,支持单点修改)
洛谷P3374 //询问区间和,支持单点修改 #include <cstdio> using namespace std; ; struct treetype { int l,r,sum; ...
随机推荐
- 浏览器对MP4视频 帧宽度 高度的兼容性
传入oss后 或者 本地 拖动到 浏览器 谷歌 都不能播放 Edge 可以播放 但 Edge不支持 本地拖入 播放 搜狗浏览器 同谷歌
- HTTP要点概述:十,内容协商
一,内容协商(Content Negotiation) 同一个Web网站可能存在很多份相同内容的页面,比如英文版和中文版的Web页面,它们内容上相同,但是使用语言不同.比如大家进入英文版的google ...
- 【Silverlight】Bing Maps学习系列(一):开发前的准备工作
[Silverlight]Bing Maps学习系列(一):开发前的准备工作 微软推出的Bing Maps地图引擎,对外开放了Silverlight和Ajax两种客户端API,同时微软针对全球地图还推 ...
- 第十四周 Leetcode 315. Count of Smaller Numbers After Self(HARD) 主席树
Leetcode315 题意很简单,给定一个序列,求每一个数的右边有多少小于它的数. O(n^2)的算法是显而易见的. 用普通的线段树可以优化到O(nlogn) 我们可以直接套用主席树的模板. 主席树 ...
- 第八届河南省省赛 A.挑战密室
挑战密室 时间限制: ms | 内存限制: KB 难度: 描述 R组织的特工Dr. Kong 为了寻找丢失的超体元素,不幸陷入WTO密室.Dr. Kong必须尽快找到解锁密码逃离,否则几分钟之后,WT ...
- JavaScript--History 对象
history对象记录了用户曾经浏览过的页面(URL),并可以实现浏览器前进与后退相似导航的功能. 注意:从窗口被打开的那一刻开始记录,每个浏览器窗口.每个标签页乃至每个框架,都有自己的history ...
- [Qt Creator 快速入门] 第1章 Qt Creator简介
Qt Creator 是一个跨平台的.完整的 Qt 集成开发环境,其中包括了高级C++代码编辑器.项目和生成管理工具.集成的上下文相关的帮助系统.图形化调试器.代码管理和浏览工具等.这一章先对 Qt ...
- mysqlbinlog(日志管理工具)
mysqlbinlog用于处理二进制的日志文件,如果想要查看这些日志文件的文本内容,就需要使用mysqlbinlog工具. 1.mysqlbinlog命令的语法 shell > mysqlbin ...
- 6.13---example
example如何使用?简单查询这个例子展示了如何用生成后的Example类去生成一个简单的where子句: TestTableExample example = new TestTableExamp ...
- 浅谈css的行内类型标签和块级标签
常用标签的行内类型标签有:a.span.img:块级标签有:div.p.h1~6.ul.ol.li.dl.dt.dd. 行内类型标签的特征:标签的大小由标签的内容决定,不能设置width和height ...