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/ 题目:
随机推荐
- linux备忘录-例行性工作排程 (crontab)
例行性工作排程 例行性工作排程分为两类 at at是只执行一次就结束的指令安排.要想使用at,必须要有atd服务的支持. crontab crontab是每隔一段时间自动执行的指令安排.crontab ...
- MySQL日常管理
DB2最佳分页语句 SELECT * FROM ( SELECT inner2_.*, ROWNUMBER() OVER(ORDER BY ORDER OF inner2_) AS rownumber ...
- ajax中用jsonp接收json数据
最近在做查快递网页时遇到一个问题,调用的快递100的api,但是快递100api不允许跨域请求,就是用127.0.0.1发的请求会直接被拦截. 只是个简单的网页,不想自己做服务器转发,最后找到了一个y ...
- 面试题中经常遇到的SQL题:删除重复数据,保留其中一条
如题,解决思路如下: 1.首先我们需要找出拥有重复数据的记录 ---以name字段分组 select Name,COUNT(Name) as [count] from Permission group ...
- UITableView性能优化【本文摘自智车芯官网】
UITableView是个表格视图,可以在表格行空间中添加多个子控件,UITableView继承了UIScrollView,默认状态下可以堆单元格进行滚动,所有的UITableViewControll ...
- 在网站中配置MIME类型
经常会遇到这样的情况,某种类型的文件不能够正常下载,*.7z,自定义的文件类型等,需要在配置文件里配置后才能正常下载. 打开Web.Config文件: <system.webServer> ...
- Win10 1803安装Ubuntu1804子系统
1.win10应用商店选择Ubuntu1804安装 点击打开会提示https://docs.microsoft.com/zh-cn/windows/wsl/install-win10 2.用管理员po ...
- hdu 2527 Safe Or Unsafe (哈夫曼树)
Safe Or Unsafe Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- [Leetcode] remove element 删除元素
Given an array and a value, remove all instances of that value in place and return the new length. T ...
- URAL1696 Salary for Robots
题目戳这里. 最长下降子序列单调队列求法. \(f_{i,j,k}\)表示考虑前\(i\)个数,\(g_1 = j,g_2 = k\)的方案数.转移: \[f_{i,j,k} = \sum_{p = ...