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 ...
随机推荐
- <!--[if IE 9]>....<!end if-->
1.页面里面经常看到类似[if it IE 9],表示的是限定某些浏览器版本才能执行的语句. ! [if ! IE] 含义:如果不是IE It [if it IE 9] 含义:如果是IE9 Ite [ ...
- ArrayAdapter
Android Adapter:ArrayAdapter篇 版权声明:本文为博主原创文章,未经博主允许不得转载.微博:厉圣杰源码:AndroidDemo/Notification文中如有纰漏,欢迎大家 ...
- SQL Tuning 基础概述03 - 使用sql_trace和10046事件跟踪执行计划
1.使用sql_trace跟踪执行计划 1.1 当前session跟踪: alter session set sql_trace = true; //开始sql_trace alter session ...
- Python爬虫小白入门(三)BeautifulSoup库
# 一.前言 *** 上一篇演示了如何使用requests模块向网站发送http请求,获取到网页的HTML数据.这篇来演示如何使用BeautifulSoup模块来从HTML文本中提取我们想要的数据. ...
- SQLServer学习笔记系列1
一.前言 一直自己没有学习做笔记的习惯,所以为了加强自己对知识的深入理解,决定将学习笔记写下来,希望向各位大牛们学习交流! 不当之处请斧正!在此感谢!这边就先从学习Sqlserver写起,自己本身对数 ...
- 我是如何进行Spring MVC文档翻译项目的环境搭建、项目管理及自动化构建工作的
感兴趣的同学可以关注这个翻译项目 . 我的博客原文 和 我的Github 前段时间翻译的Spring MVC官方文档完成了第一稿,相关的文章和仓库可以点击以下链接.这篇文章,主要是总结一下这个翻译项目 ...
- 调试关于Hibernate的程序遇到的问题
最怕的就是初学一些东西,低级的错误犯了又犯,现在总结出来以便以后不要再犯类似的错误. 一.Hibernate的延迟加载机制 在用hibernate底层访问数据库的过程忽略了延迟加载机制导致 在访问时候 ...
- HTTPS和HTTP的区别
(转自:http://www.php100.com/html/it/biancheng/2015/0209/8582.html) 总的来说,http效率更高,https安全性更高. 首先谈谈什么是HT ...
- 非域客户端的office使用RMS加密服务出现‘介绍“信息权限管理服务”’服务的提示
环境:office2007,需要使用windows RMS服务,客户机处于工作组模式,如图: 出现这个说明客户机没有发现RMS服务,可以通过导入注册表解决,如下: Windows Registry E ...
- MSCRM CRM 获取PickList 字段值函数解决方案
表单中有很多picklist字段 不想写链接stringmap代码: 实体ID查询方法: SELECT ObjectTypeCode from Entity where name='实体名称' 调 ...