codevs 1082 线段树练习 3(区间维护)
codevs 1082 线段树练习 3
给你N个数,有两种操作:
1:给区间[a,b]的所有数增加X
2:询问区间[a,b]的数的和。
第一行一个正整数n,接下来n行n个整数,
再接下来一个正整数Q,每行表示操作的个数,
如果第一个数是1,后接3个正整数,
表示在区间[a,b]内每个数增加X,如果是2,
表示操作2询问区间[a,b]的和是多少。
pascal选手请不要使用readln读入
对于每个询问输出一行一个答案
3
1
2
3
2
1 2 3 2
2 2 3
9
数据范围
1<=n<=200000
1<=q<=200000
#include<iostream>
using namespace std;
#include<cstdio>
#define N 200001
long long int sz[N],n,q,a,b,c,x;
struct node{
long long int l,r,val,delta;
node *child[];
}*root=NULL;
void input()
{
scanf("%d",&n);
for(long long int i=;i<=n;++i)
scanf("%d",&sz[i]);
}
void update(node *cur)
{
cur->val=cur->child[]->val+cur->child[]->val;
}
void bulid(node *&cur,long long int l,long long int r)
{
if(l>r) return ;
cur=new node;
cur->l=l;cur->r=r;
cur->delta=;
if(l==r)
{
cur->child[]=cur->child[]=NULL;
cur->val=sz[l];
return;
}
long long int mid=(l+r)/;
bulid(cur->child[],l,mid);
bulid(cur->child[],mid+,r);
update(cur);
}
void down(node *cur)
{
if(cur->child[])
{
long long int l1=cur->child[]->l,r1=cur->child[]->r;
cur->child[]->val+=(r1-l1+)*cur->delta;
cur->child[]->delta+=cur->delta;
}
if(cur->child[])
{
long long int l1=cur->child[]->l,r1=cur->child[]->r;
cur->child[]->val+=(r1-l1+)*cur->delta;
cur->child[]->delta+=cur->delta;
}
cur->delta=;
}
void add(node *cur,long long int l,long long int r,long long int x)
{
if(l<=cur->l&&cur->r<=r)
{
cur->val+=(cur->r-cur->l+)*x;
cur->delta+=x;
return ;
}
if(cur->delta) down(cur);
long long int mid=(cur->l+cur->r)/;
if(l<=mid) add(cur->child[],l,r,x);
if(r>mid) add(cur->child[],l,r,x);
update(cur);
}
long long int query(node *cur,long long int l,long long int r)
{
if(l<=cur->l&&cur->r<=r)
{
return cur->val;
}
if(cur->delta) down(cur);
long long int ans=,mid=(cur->l+cur->r)/;
if(l<=mid) ans+=query(cur->child[],l,r);
if(r>mid) ans+=query(cur->child[],l,r);
return ans;
}
int main()
{
input();
bulid(root,,n);
scanf("%d",&q);
while(q--)
{
scanf("%d",&x);
if(x==)
{
scanf("%d%d%d",&a,&b,&c);
add(root,a,b,c);
}
else {
scanf("%d%d",&a,&b);
printf("%lld\n",query(root,a,b));
}
}
return ;
}
teacher's
/*数据类型必须用long long才能过*/
#include<cstdio>
#include<iostream>
using namespace std;
long long n,m;
long long sz[];
struct node
{
long long val,delta,l,r;
node * ch[];
}*root=NULL;
long long sv(node * cur)
{
return cur?cur->val:;
}
void update(node * cur)
{
cur->val=sv(cur->ch[])+sv(cur->ch[]);
}
void build(node * &cur,long long l,long long r)
{
if(l>r)return;
cur=new node;
cur->l=l;cur->r=r;cur->delta=;
if(l==r)
{
cur->val=sz[l];
cur->ch[]=cur->ch[]=NULL;
}
else
{
long long mid=(l+r)/;
build(cur->ch[],l,mid);
build(cur->ch[],mid+,r);
update(cur);
}
}
void down(node * cur)
{
if(cur->ch[])
{
cur->ch[]->delta+=cur->delta;
cur->ch[]->val+=cur->delta*(cur->ch[]->r-cur->ch[]->l+);
}
if(cur->ch[])
{
cur->ch[]->delta+=cur->delta;
cur->ch[]->val+=cur->delta*(cur->ch[]->r-cur->ch[]->l+);
}
cur->delta=;
}
void add(node * cur,long long l,long long r,long long x)
{
if(l<=cur->l&&cur->r<=r)
{
cur->delta+=x;
cur->val+=x*(cur->r-cur->l+);
}
else
{
if(cur->delta)down(cur);
long long mid=(cur->l+cur->r)/;
if(l<=mid)add(cur->ch[],l,r,x);
if(r>mid)add(cur->ch[],l,r,x);
update(cur);/*注意这个不能更少,当前区间val应该加多少,未知,要先加完他的左右孩子,再回来的时候更新它*/
}
}
long long query(node * cur,long long l,long long r)
{
if(l<=cur->l&&cur->r<=r)return cur->val;
else
{
down(cur);
long long mid=(cur->l+cur->r)/;
long long ans=;
if(l<=mid)ans+=query(cur->ch[],l,r);
if(r>mid)ans+=query(cur->ch[],l,r);
return ans;
}
}
int main()
{
long long i;
cin>>n;
for(i=;i<=n;i++)scanf("%lld",&sz[i]);
build(root,,n);
cin>>m;
for(i=;i<m;i++)
{
long long a,b,c,d;
scanf("%lld",&a);
if(a==)
{
scanf("%lld%lld%lld",&b,&c,&d);
add(root,b,c,d);
}
else if(a==)
{
scanf("%lld%lld",&b,&c);
printf("%lld\n",query(root,b,c));
}
}
return ;
}
mine
codevs 1082 线段树练习 3(区间维护)的更多相关文章
- codevs 1082 线段树练习 3 区间更新+延迟标记
题目描述 Description 给你N个数,有两种操作: 1:给区间[a,b]的所有数增加X 2:询问区间[a,b]的数的和. 输入描述 Input Description 第一行一个正整数n,接下 ...
- codevs 1082 线段树区间求和
codevs 1082 线段树练习3 链接:http://codevs.cn/problem/1082/ sumv是维护求和的线段树,addv是标记这歌节点所在区间还需要加上的值. 我的线段树写法在运 ...
- codevs 1082 线段树练习3
1082 线段树练习 3 时间限制: 3 s 空间限制: 128000 KB 题目等级 : 大师 Master 题解 题目描述 Description 给你N个数,有两种操作: 1: ...
- Codevs 1082 线段树练习 3
1082 线段树练习 3 时间限制: 3 s 空间限制: 128000 KB 题目等级 : 大师 Maste 传送门 题目描述 Description 给你N个数,有两种操作: 1:给区间[a,b]的 ...
- 【树状数组区间修改区间求和】codevs 1082 线段树练习 3
http://codevs.cn/problem/1082/ [AC] #include<bits/stdc++.h> using namespace std; typedef long ...
- codevs 1082 线段树练习3 (线段树)
题目: 题目描述 Description 给你N个数,有两种操作: 1:给区间[a,b]的所有数增加X 2:询问区间[a,b]的数的和. 输入描述 Input Description 第一行一个正整数 ...
- codevs 1082 线段树练习 3 --分块练习
时间限制: 3 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 给你N个数,有两种操作: 1:给区间[a,b]的所有数增加X 2:询问区间[ ...
- 【codevs】1082 线段树练习 3 <区间修改+区间和>
题目连接 http://codevs.cn/problem/1082/ Description 给你N个数,有两种操作: 1:给区间[a,b]的所有数增加X 2:询问区间[a,b]的数的和. In ...
- codevs 1081 线段树练习 2 区间更新 单点查询 无lazy
题目描述 Description 给你N个数,有两种操作 1:给区间[a,b]的所有数都增加X 2:询问第i个数是什么? 输入描述 Input Description 第一行一个正整数n,接下来n行n ...
随机推荐
- Log4Net生成出现未引用错误解决方法
1.步骤一: 2.步骤二: 明明添加了引用怎么还提示找不到命名空间呢.解决这个问题很简单,右键项目选择属性: 3.步骤三:换成.NET Framework 4即可,解决! 4.两个有啥区别? Micr ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(55)-工作流设计-表单布局
系列目录 前言:这一节比较有趣.基本纯UI,但是不是很复杂 有了实现表单的打印和更加符合流程表单方式,我们必须自定义布局来适合业务场景打印!我们想要什么效果?看下图 (我们没有布局之前的表单和设置布局 ...
- TortoiseGIT创建及合并分支
一.创建分支 项目右键 => TortoiseGit(T) => 创建分支,然后右键切换到刚刚创建的分支,新增/修改一个文件,提交分支到远端服务器,推送成功之后分支就创建好了. 二.合并分 ...
- Quartz.NET Windows 服务示例
想必大家在项目中处理简单的后台持续任务或者定时触发任务的时候均使用 Thread 或者 Task 来完成,但是项目中的这种需求一旦多了的话就得将任务调度引入进来了,那今天就简单的介绍一下 Quartz ...
- Vertica删除历史分区数据
假设test用户下创建的t_jingyu表 vsql -Utest -wtestpwd create table t_jingyu( col1 int, col2 varchar, col3 time ...
- DotNet程序配置文件
在实际的项目开发中,对于项目的相关信息的配置较多,在.NET项目中,我们较多的将程序的相关配置直接存储的.config文件中,例如web.config和app.config. .NET中配置文件分为两 ...
- php内核分析(六)-opcode
这里阅读的php版本为PHP-7.1.0 RC3,阅读代码的平台为linux 查看opcode php是先把源码解析成opcode,然后再把opcode传递给zend_vm进行执行的. // 一个op ...
- 【转】基于.NET平台常用的框架整理
自从学习.NET以来,优雅的编程风格,极度简单的可扩展性,足够强大开发工具,极小的学习曲线,让我对这个平台产生了浓厚的兴趣,在工作和学习中也积累 了一些开源的组件,就目前想到的先整理于此,如果再想到, ...
- Maven+Spring+Spring MVC+MyBatis+MySQL,搭建SSM框架环境【转】
项目建设完成之后的结构: 数据库的表结构如下: 环境建设:搭建Maven环境.Tomcat环境.需要MySql 数据库支持,使用的编程工具Eclipse (这些是前期准备): 开始创建工程: 1.创建 ...
- JQuery中$.ajax()方法参数详解
url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. type: 要求为String类型的参数,请求方式(post或get)默认为get.注意其他http请求方法,例如put和 ...