codevs 线段树练习ⅠⅡⅢ
一行N个方格,开始每个格子里都有一个整数。现在动态地提出一些问题和修改:提问的形式是求某一个特定的子区间[a,b]中所有元素的和;修改的规则是指定某一个格子x,加上或者减去一个特定的值A。现在要求你能对每个提问作出正确的回答。1≤N<100000,,提问和修改的总数m<10000条。
输入文件第一行为一个整数N,接下来是n行n个整数,表示格子中原来的整数。接下一个正整数m,再接下来有m行,表示m个询问,第一个整数表示询问代号,询问代号1表示增加,后面的两个数x和A表示给位置X上的数值增加A,询问代号2表示区间求和,后面两个整数表示a和b,表示要求[a,b]之间的区间和。
共m行,每个整数
6
4
5
6
2
1
3
4
1 3 5
2 1 4
1 1 9
2 2 6
22
22
1≤N≤100000, m≤10000 。
#include <cstdio>
#include <iostream>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn=;
using namespace std;
int sum[maxn<<]; void PushUP(int rt)
{
sum[rt]=sum[rt<<]+sum[rt<<|];//将两条小区间合并成一个大区间
} void build(int l,int r,int rt)
{
if (l==r)//最底层的节点
{
scanf("%d",&sum[rt]);//读入节点的值
return;
}
int m=(l+r)>>;//分成两个区间
build(lson);//分别搞搞左右两个区间
build(rson);
PushUP(rt);//将最底层的节点的值传入上层节点
} void update(int p,int add,int l,int r,int rt)
{
if (l==r)//往最底层节点加上add
{
sum[rt]+=add;
return;
}
int m=(l+r)>>;//取中间节点
if (p<=m)update(p,add,lson);//找到节点的儿子并且是p的祖先的节点,递归到p
else update(p,add,rson);
PushUP(rt);//更新p祖先节点的值
} int query(int L,int R,int l,int r,int rt)//区间查询
{//L,R是要查询的区间和,l、r是目前的区间,rt是目前的节点
if (L<=l&&r<=R)
{
return sum[rt];//如果当前区间是所求区间的一部分,就加上这段区间
}
int m=(l+r)>>;//二分当前区间
int ret=;//为所求区间的数值和
if (L<=m)ret+=query(L,R,lson);//加上所需区间
if (R>m)ret+=query(L,R,rson);
return ret;
} int main()
{
int n,m;
scanf("%d",&n);//区间为1-n
build(,n,);//建树
int cz;
cin>>m;
while(m--)
{
scanf("%d",&cz);
int a,b;
scanf("%d%d",&a,&b);
if (cz==)printf("%d\n",query(a,b,,n,));//query 询问区间的总值
//else if (cz==3)update(a,-b,1,n,1);//sub 往第a个数里减b
else update(a,b,,n,);//往第a个数中加b
}
return ;
}
给你N个数,有两种操作
1:给区间[a,b]的所有数都增加X
2:询问第i个数是什么?
第一行一个正整数n,接下来n行n个整数,再接下来一个正整数Q,表示操作的个数. 接下来Q行每行若干个整数。如果第一个数是1,后接3个正整数a,b,X,表示在区间[a,b]内每个数增加X,如果是2,后面跟1个整数i, 表示询问第i个位置的数是多少。
对于每个询问输出一行一个答案
3
1
2
3
2
1 2 3 2
2 3
5
数据范围
1<=n<=100000
1<=q<=100000
#include <cstdio>
#include <iostream>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn=;
using namespace std;
int sum[maxn<<]; void PushUP(int rt)
{
sum[rt]=sum[rt<<]+sum[rt<<|];//将两条小区间合并成一个大区间
} void build(int l,int r,int rt)
{
if (l==r)//最底层的节点
{
scanf("%d",&sum[rt]);//读入节点的值
return;
}
int m=(l+r)>>;//分成两个区间
build(lson);//分别搞搞左右两个区间
build(rson);
PushUP(rt);//将最底层的节点的值传入上层节点
} void update(int p,int add,int l,int r,int rt)
{
if (l==r)//往最底层节点加上add
{
sum[rt]+=add;
return;
}
int m=(l+r)>>;//取中间节点
if (p<=m)update(p,add,lson);//找到节点的儿子并且是p的祖先的节点,递归到p
else update(p,add,rson);
PushUP(rt);//更新p祖先节点的值
} int query(int L,int R,int l,int r,int rt)//区间查询
{//L,R是要查询的区间和,l、r是目前的区间,rt是目前的节点
if (L<=l&&r<=R)
{
return sum[rt];//如果当前区间是所求区间的一部分,就加上这段区间
}
int m=(l+r)>>;//二分当前区间
int ret=;//为所求区间的数值和
if (L<=m)ret+=query(L,R,lson);//加上所需区间
if (R>m)ret+=query(L,R,rson);
return ret;
} int main()
{
int n,m;
scanf("%d",&n);//区间为1-n
build(,n,);//建树
int cz;
cin>>m;
while(m--)
{
scanf("%d",&cz);
int a,b,c;
if (cz==)
{
cin>>a>>b>>c;
for(int i=a;i<=b;++i)
update(i,c,,n,);
}
else
{
cin>>a;
cout<<query(a,a,,n,)<<endl;
}
}
return ;
}
给你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<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define N 500005
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define ll long long
ll sum[N*];
int visit[N*];
void pushUp(int rt)
{
sum[rt]=sum[rt<<]+sum[rt<<|];
} void build(int l,int r,int rt)
{
visit[rt]=;
if(l==r)
{
scanf("%lld",&sum[rt]);
return ;
}
int m=(l+r)>>;
build(lson);
build(rson);
pushUp(rt);
} void pushDown(int rt,int d)
{
if(visit[rt]!=)
{ visit[rt<<]+=visit[rt];
visit[rt<<|]+=visit[rt];
sum[rt<<|]+=(ll)(d>>)*visit[rt];
sum[rt<<]+=(ll)(d-(d>>))*visit[rt];
visit[rt]=;
}
} void update(int L,int R,int c,int l,int r,int rt)
{
if(L<=l && R>=r)
{
visit[rt]+=c;
sum[rt]+=(r-l+)*c;
return ;
}
pushDown(rt,r-l+);
int m=(l+r)>>;
if(L<=m)
update(L,R,c,lson);
if(R>m)
update(L,R,c,rson);
pushUp(rt);
} ll query(int L,int R,int l,int r,int rt)
{
if(L<=l&&R>=r)
{
return sum[rt];
}
pushDown(rt,r-l+);
int m=(l+r)>>;
ll ret=;
if(L<=m)
ret+=query(L,R,lson);
if(R>m)
ret+=query(L,R,rson);
return ret;
} int main()
{
int n,q,a,b,c;
int s;
scanf("%d",&n);
build(,n,);
cin>>q;
while(q--)
{
scanf("%d",&s);
if(s==)
{
scanf("%d%d%d",&a,&b,&c);
update(a,b,c,,n,);
}
else if(s==)
{
scanf("%d%d",&a,&b);
printf("%lld\n",query(a,b,,n,));
}
}
return ;
}
codevs 线段树练习ⅠⅡⅢ的更多相关文章
- [codevs]线段树练习5
http://codevs.cn/problem/4927/ #include <iostream> #include <cstdio> #include <algori ...
- codevs 1082 线段树练习 3(区间维护)
codevs 1082 线段树练习 3 时间限制: 3 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 给你N个数,有两种操作: 1:给区 ...
- codevs 1576 最长上升子序列的线段树优化
题目:codevs 1576 最长严格上升子序列 链接:http://codevs.cn/problem/1576/ 优化的地方是 1到i-1 中最大的 f[j]值,并且A[j]<A[i] .根 ...
- codevs 1080 线段树点修改
先来介绍一下线段树. 线段树是一个把线段,或者说一个区间储存在二叉树中.如图所示的就是一棵线段树,它维护一个区间的和. 蓝色数字的是线段树的节点在数组中的位置,它表示的区间已经在图上标出,它的值就是这 ...
- codevs 1082 线段树区间求和
codevs 1082 线段树练习3 链接:http://codevs.cn/problem/1082/ sumv是维护求和的线段树,addv是标记这歌节点所在区间还需要加上的值. 我的线段树写法在运 ...
- codevs 1080 线段树练习
链接:http://codevs.cn/problem/1080/ 先用树状数组水一发,再用线段树水一发 树状数组代码:84ms #include<cstdio> #include< ...
- 线段树练习 codevs 1080
/* codevs 1080 线段树练习 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description 一行N个方格,开 ...
- codevs 1080 线段树练习 CDQ分治
codevs 1080 线段树练习 http://codevs.cn/problem/1080/ 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description 一行N个 ...
- 4163 hzwer与逆序对 (codevs + 权值线段树 + 求逆序对)
题目链接:http://codevs.cn/problem/4163/ 题目:
随机推荐
- MySQL统计数据库大小
select concat(truncate(sum(data_length)/1024/1024,2),'mb') as data_size, concat(truncate(sum(max_dat ...
- mysql语法总结
增: 删: 改: 查: 索引: 建: alter table: sql一些常用的经典语句,最后是select as的用法
- Struts2—整合Spring
Struts2—整合Spring Spring框架是一个非常优秀的轻量级java EE容器,大部分javaEE应用,都会考虑使用Spring容器来管理应用中的组件. Struts2是一个MVC框架,是 ...
- libevent 多线程
对于evbuffer,如果libevent使用了evthread_use_pthreads();那么所有的单个evbuffer操作就已经是原子的了,调用操作相关的接口进去就上锁,出来解锁,那么 evb ...
- 正则表达式之旅_sed_awk
谈谈正则表达式这个东西: 我想作为一个程序员,正则表达式大家绝对不陌生. 正则表达式好像一个有限则动机.主要作用是匹配,但是同时因为这个功能,我们可以扩展很多其他用法 像很多语言都引人了正则表达式:j ...
- 算法(6)3Sum Closest
kSum问题是一类问题,基本的方法是两个循环,其他一个查找,但是今天碰到了一个超级棘手的问题,是3Sum问题的一个变型 问题:给定一个数组,给定一个整数k,要求找出在数组中找到3个整数,使得这三个整数 ...
- Java中输入输出流
InputStream:所有字节输入流的所有类的超类. read(byte[] b)从输入流中读取一定数量的字节,并将其存储在缓冲数组b中 reset()将此流重新定位到最后一次对此流调用mark方法 ...
- typescript 简版跳一跳
typescript 简版跳一跳 学习typescript,第一步应该是学习官方文档,理解最基础的语法.第二步开始用typescript实现一些js+css 或者canvas类型的游行.现在开始我们用 ...
- #define、const、typedef的区别
#define.const.typedef的区别 #define 并不是定义变量, 只是用来做文本替换 例如: #define PI 3.1415926 float angel; angel=30*P ...
- 接到新数据库时,分析业务常用的SQL语句
USE DataBaseName--清空当前GridView显示,释放内存: SELECT GETDATE() --数据库关系图 SELECT * FROM sysdiagrams --列出所有表 S ...