【对询问分块】CODEVS1080 线段树练习

#include<cstdio>
#include<cmath>
using namespace std;
#define N 100001
int sum[N],a[N],n,m,last,op[N],Xs[N],Ys[N];
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;++i)
	  scanf("%d",&a[i]);
	scanf("%d",&m);
	int sz=sqrt(m); if(!sz) sz=1;
	for(int i=1;i<=m;++i)
	  {
	  	scanf("%d%d%d",&op[i],&Xs[i],&Ys[i]);
	  	if(i%sz==1||sz==1)
	  	  {
	  	  	for(int j=last;j<i;++j)
	  	  	  if(op[j]==1)
				a[Xs[j]]+=Ys[j];
	  	  	for(int j=1;j<=n;++j)
			  sum[j]=a[j]+sum[j-1];
	  	  	last=i;
	  	  }
	  	if(op[i]==2)
	  	  {
	  	  	int ans=sum[Ys[i]]-sum[Xs[i]-1];
	  	  	for(int j=last;j<i;++j)
			  if(op[j]==1&&Xs[j]>=Xs[i]&&Xs[j]<=Ys[i])
			    ans+=Ys[j];
			printf("%d\n",ans);
	  	  }
	  }
	return 0;
}
时间: 2024-10-27 01:10:05

【对询问分块】CODEVS1080 线段树练习的相关文章

codevs1080线段树练习

1080 线段树练习(http://codevs.cn/problem/1080/) 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 一行N个方格,开始每个格子里都有一个整数.现在动态地提出一些问题和修改:提问的形式是求某一个特定的子区间[a,b]中所有元素的和:修改的规则是指定某一个格子x,加上或者减去一个特定的值A.现在要求你能对每个提问作出正确的回答.1≤N<100000,,提问和修改的总数m<10000条. 输入

魔性の分块 | | jzoj1243 | | 线段树の暴力

题目的打开方式是酱紫的 然而作为一只蒻蒟根本不会线段树该怎么办呢? sro  MZX  orz 是这样说的:用分块啊! 分块 根据紫萱学姐的教程,分块的打开姿势是这样的: 我们要对一个数组进行整体操作,那么我们就可以把他们分成元素相等的n部分,由于n部分的最大值很容易找,也就是我们可以预处理出最大值(更何况此题最开始数组赋初值为0)我们要查询第k1-k2个数的最大值,就返回k1-k2所对应的块的最大值即可, 好,作为一只蒻蒟根本不知所云? 用一张图解来表示一下就是酱紫 红线代表整个数组,底下数轴

中南OJ1551: Longest Increasing Subsequence Again(分块+离散化线段树)

1551: Longest Increasing Subsequence Again Time Limit: 2 Sec  Memory Limit: 256 MB Submit: 29  Solved: 15 [Submit][Status][Web Board] Description Give you a numeric sequence. If you can demolish arbitrary amount of numbers, what is the length of the

[SCOI2010]序列操作[分块or线段树]

/* 本题的难度在于标记的下放. 下面说一下我的做法: 1.覆盖标记:直接打上就好了 2.取反标记: <1>如果有tag标记,将tag标记取反,退出. <2>如果有rev标记,直接退出 <3>无标记,打上rev标记,退出 维护: sum(当前区间和),lss1(区间从左端点连续1的长度),rss1(区间从右端点连续1的长度),sc1(区间连续1的长度) lss0,rss0,sc0同理.tag(覆盖标记和取反标记整一起了) */ #include<cmath>

codevs 1082 线段树练习 3 --分块练习

时间限制: 3 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 给你N个数,有两种操作: 1:给区间[a,b]的所有数增加X 2:询问区间[a,b]的数的和. 输入描述 Input Description 第一行一个正整数n,接下来n行n个整数, 再接下来一个正整数Q,每行表示操作的个数, 如果第一个数是1,后接3个正整数, 表示在区间[a,b]内每个数增加X,如果是2, 表示操作2询问区间[a,b]的和是多少. pascal选手请不要使用

CF-558E (线段树/分块)

解题思路: 很显然突破口就是字符集比较小,分块和线段树都能A 话说线段树时间是分块5倍啊 代码(线段树): 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define lll spc<<1 5 #define rrr spc<<1|1 6 struct int_26{ 7 int has[30]; 8 void res(void) 9 { 10 memset(has

讲解——线段树

   讲解--线段树 O.引例 A.给出n个数,n<=100,和m个询问,每次询问区间[l,r]的和,并输出. 一种回答:这也太简单了,O(n)枚举搜索就行了. 另一种回答:还用得着o(n)枚举,前缀和o(1)就搞定. 那好,我再修改一下题目. B.给出n个数,n<=100,和m个操作,每个操作可能有两种:1.在某个位置加上一个数:2.询问区间[l,r]的和,并输出. 回答:o(n)枚举. 动态修改最起码不能用静态的前缀和做了. 好,我再修改题目: C.给出n个数,n<=1000000,

HDU 5107 线段树扫描线

给出N个点(x,y),每个点有一个高度h 给出M次询问,问在(x,y)范围内第k小的高度是多少,没有输出-1 (k<=10) 线段树扫描线 首先离散化Y坐标,以Y坐标建立线段树 对所有的点和询问进行离线操作,将询问和点按照x,y的大小排序,从左向右,从下向上,对于相同的(x,y)插入点在询问点之前 线段树的每个节点维护10个高度,每次询问[0,mark[i].y]的第mark[i].h高的值即可 #include "stdio.h" #include "string.h

hdu 2665 可持久化线段树求区间第K大值(函数式线段树||主席树)

http://acm.hdu.edu.cn/showproblem.php?pid=2665 Problem Description Give you a sequence and ask you the kth big number of a inteval. Input The first line is the number of the test cases. For each test case, the first line contain two integer n and m (