牛客练习赛28 B数据结构(线段树)
链接:https://www.nowcoder.com/acm/contest/200/B
来源:牛客网
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
输入描述:
第一行两个数n,m 接下来一行n个数表示初始序列 就下来m行每行第一个数为操作方法opt, 若opt=1或者opt=2,则之后跟着两个数为l,r 若opt=3或者opt=4,则之后跟着三个数为l,r,x 操作意思为题目描述里说的
输出描述:
对于每一个操作1,2,输出一行表示答案
输入例子:
5 6
1 2 3 4 5
1 1 5
2 1 5
3 1 2 1
4 1 3 2
1 1 4
2 2 3
输出例子:
15
55
16
41
-->
备注:
对于100%的数据 n=10000,m=200000 (注意是等于号) 保证所有询问的答案在long long 范围内 解题思路:这题目就是纯粹考查代码能力,板子没记牢,就因为下推少了个+号和*号就一直WA,他妈竟然样例竟然又能过,比赛一结束竟然就发现了,一提交就AC了,真是要气死了。。。
思路就是这样,复制下出题人的题解吧。
显然,线段树
窝们记录4个东西,区间和tree[root][0],区间平方和 tree[root][1],乘法懒标记 add2[root],加法懒标记add1[root] 。
查询的话就是常规查询,打标记就是线段树2板子一样,
初值:add1[root]=0,add2[root]=1;
加法:add1[root]+=dx
乘法:add2[root]*=dx;
然后考虑更新答案
当前区间[l,r] ,当前节点root,这里面每个元素都变成了( a[i]为更新后, x[i]为更新前)

所以

然后就标准线段树板子
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define maxn 10005
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
long long n,m,tree[maxn<<][],add1[maxn<<],add2[maxn<<]; void pushup(long long root)
{
tree[root][]=tree[root<<][]+tree[root<<|][];
tree[root][]=tree[root<<][]+tree[root<<|][];
}
void pushdown1(long long l,long long r,long long root)
{ //加法下推
if(add1[root])
{
add1[root<<]+=add1[root]; //+号不能少,切记
add1[root<<|]+=add1[root];
long long x=tree[root<<][];
long long y=tree[root<<|][];
tree[root<<][]+=l*add1[root];
tree[root<<|][]+=r*add1[root];
tree[root<<][]+=*x*add1[root]+l*add1[root]*add1[root];
tree[root<<|][]+=*y*add1[root]+r*add1[root]*add1[root];
add1[root]=;
}
}
void pushdown2(long long l,long long r,long long root)
{ //乘法下推
if(add2[root]!=)
{
add2[root<<]*=add2[root]; //*号不能少,切记
add2[root<<|]*=add2[root];
tree[root<<][]*=add2[root];
tree[root<<|][]*=add2[root];
tree[root<<][]*=add2[root]*add2[root];
tree[root<<|][]*=add2[root]*add2[root];
add2[root]=;
}
}
void build(long long l,long long r,long long root)
{
add1[root]=;
add2[root]=;
if(l==r)
{
scanf("%lld",&tree[root][]);
tree[root][]=tree[root][]*tree[root][];
return;
}
long long mid=(l+r)>>;
build(lson);
build(rson);
pushup(root);
}
void update1(long long L,long long R,long long C,long long l,long long r,long long root)
{ //加法更新
if(L<=l&&r<=R)
{
long long x=tree[root][];
tree[root][] += (r-l+)*C;
tree[root][] += *x*C+(r-l+)*C*C;
add1[root] += C;
return ;
}
long long mid = (l+r)/;
pushdown2(mid-l+1,r-mid,root); pushdown1(mid-l+,r-mid,root);
if(L<=mid)
update1(L,R,C,lson);
if(R>mid)
update1(L,R,C,rson);
pushup(root);
}
void update2(long long L,long long R,long long C,long long l,long long r,long long root)
{ //乘法更新
if(L<=l&&r<=R)
{
tree[root][] *= C;
tree[root][] *= C*C;
add2[root] *= C; if(add1[root]) add1[root] *= C;
return ;
}
long long mid = (l+r)/;
pushdown2(mid-l+,r-mid,root); pushdown1(mid-l+1,r-mid,root);
if(L<=mid)
update2(L,R,C,lson);
if(R>mid)
update2(L,R,C,rson);
pushup(root);
}
long long query(long long L,long long R,long long c,long long l,long long r,long long root)
{
if(L<=l&&R>=r)
{
if(c==)
return tree[root][];
if(c==)
return tree[root][];
}
long long ans=,mid=(l+r)>>;
pushdown2(mid-l+,r-mid,root); pushdown1(mid-l+1,r-mid,root);
if(L<=mid)
ans+=query(L,R,c,lson);
if(R>mid)
ans+=query(L,R,c,rson);
return ans;
} int main()
{
cin>>n>>m;
build(,n,);
while(m--)
{
long long op,x,y,val;
scanf("%lld",&op);
if(op==||op==)
{
scanf("%lld%lld",&x,&y);
printf("%lld\n",query(x,y,op,,n,));
}
else if(op==||op==)
{
scanf("%lld%lld%lld",&x,&y,&val);
if(op==)
update2(x,y,val,,n,);
else
update1(x,y,val,,n,);
}
}
return ;
}
牛客练习赛28 B数据结构(线段树)的更多相关文章
- 牛客网 牛客练习赛11 A.假的线段树
看不懂题意,而且太菜,写了两道就溜了... A.假的线段树 链接:https://www.nowcoder.com/acm/contest/59/A来源:牛客网 时间限制:C/C++ 1秒,其他语言2 ...
- 牛客练习赛28B (经典)【线段树】
<题目链接> qn姐姐最好了~ qn姐姐给你了一个长度为n的序列还有m次操作让你玩, 1 l r 询问区间[l,r]内的元素和 2 l r 询问区间[l,r]内的元 ...
- 线段树 B数据结构 牛客练习赛28
链接:https://ac.nowcoder.com/acm/contest/200/B来源:牛客网 题目描述 qn姐姐最好了~ qn姐姐给你了一个长度为n的序列还有m次操作让你玩, ...
- 牛客练习赛16 B 漂亮的树【哈希hash/思维】
链接:https://www.nowcoder.com/acm/contest/84/B 来源:牛客网 题目描述 街上有n棵树,标号为1...n,第i棵树的高度为ai. 定义这n棵树是漂亮的,当且仅当 ...
- 牛客练习赛28 E迎风舞 (三分查找)
链接:https://www.nowcoder.com/acm/contest/200/E来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言5242 ...
- 牛客 Rabbit的数列 (线段树维护值为x的个数+区间覆盖)
https://ac.nowcoder.com/acm/contest/907/C 链接:https://ac.nowcoder.com/acm/contest/907/C来源:牛客网 题目描述 Ra ...
- 牛客练习赛22-E.简单数据结构1(扩展欧拉定理降幂 +树状数组)
链接:E.简单数据结构1 题意: 给一个长为n的序列,m次操作,每次操作: 1.区间加 2.对于区间,查询 ,一直到- 请注意每次的模数不同. 题解:扩展欧拉定理降幂 对一个数p取log(p)次的 ...
- 牛客练习赛52 B题【树状数组维护区间和{查询区间和,如果区间元素重复出现则计数一次}】补题ing
[题目] 查询区间和,如果区间元素重复出现则计数一次. 链接:https://ac.nowcoder.com/acm/contest/1084/B [题解] 将询问按r排序,维护每个数最后出现的位置, ...
- 牛客练习赛28-B(线段树,区间更新)
牛客练习赛28 - B 传送门 题目 qn姐姐最好了~ qn姐姐给你了一个长度为n的序列还有m次操作让你玩, 1 l r 询问区间[l,r]内的元素和 2 l r 询问区间[l,r]内的 ...
随机推荐
- Linux下面将windows写的脚本转换成 Linux 格式的文件
1.接着上一篇blog 发现有一个问题 vim 打开文件 发现最下面有一行信息: 2. 里面有一些 不一样的地方. linux里面没法执行 ,如果想执行的话 可以输入命令 :set fileforma ...
- Linux基础学习笔记3-用户权限
本章内容 用户user 令牌token,identity Linux用户:Uername/UID 管理员:root,0 普通用户:1-65535 系统用户:1-499,1-999(Centos7) 对 ...
- linux audit (9)--生成audit报表
aureport这个命令可以生成一个总结性的柱状图报表,默认情况下,在/var/log/audit目录下的所有日志文件都会生成一个报表,也可以使用如下命令来指定一个不同的文件,aureport opt ...
- jenkins中通过execute shell启动的进程会被杀死的问题
在jenkins中配置自动更新部署项目时,如果采取用execute shell启动/关闭tomcat,会发现可以进行关闭tomcat, 但是无法启动tomcat,虽然构建会显示执行成功,但是查看进程, ...
- linux Vi使用
前言 在嵌入式linux开发中,进行需要修改一下配置文件之类的,必须使用vi,因此,熟悉 vi 的一些基本操作,有助于提高工作效率. 一,模式vi编辑器有3种模式:命令模式.输入模式.末行模式. ...
- atlassian、jira账户无法注册来这里
进入https://www.atlassian.com/try 注册成功 登陆 再次到邮箱点击链接 登陆成功(已经处于登陆状态:此时你已经拥有一个atlassian账户了)
- poj2739(尺取法+质数筛)
题意:给你一个数,问这个数能否等于一系列连续的质数的和: 解题思路:质数筛打出质数表:然后就是尺取法解决: 代码: #include<iostream> #include<algor ...
- POJ 2823 滑动窗口 单调队列
https://vjudge.net/problem/POJ-2823 中文:https://loj.ac/problem/10175 题目 给一个长度为 $N$ 的数组,一个长为 $K$ 的滑动窗体 ...
- 【数学建模】day05-微分方程建模
很多问题,归结起来是微分方程(组)求解的问题.比如:为什么使用三级火箭发射卫星.阻滞增长人口模型的建立…… MATLAB提供了良好的微分方程求解方案. 一.MATLAB求微分方程的符号解 matlab ...
- 使用Java泛型返回动态类型
返回一个指定类型的集合,并且clazz必须继承IGeoLog对象或者是其本身 <T extends IGeoLog> List<T> getLogListSql(Class&l ...