HUD2795 线段树(单点更新)

题目中给出的h和w范围均大,其实n的最大范围才200000,所以我们建立的线段树大小为min(h,n),线段树的每一个节点包含一个变量c,记录当前区间内还剩下的可以put on的最大长度。插入一个数时,如果该数大于该区间最大值,则返回-1,说明put on不了。否则将它插入到页节点,并返回插入的下标,接着一定不要忘记更新父节点的c值。

#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = 200001;
struct Tnode{
	int e, b;
	int c;
};
int h, w, n,ans;;
Tnode tree[4 * MAXN];
void Create(int v, int b, int e){
	tree[v].b = b;
	tree[v].e = e;
	tree[v].c = w;
	if (e > b){
		int mid = (b + e) >> 1;
		Create(2 * v + 1, b, mid);
		Create(2 * v + 2, mid + 1, e);
	}
}
void Insert(int v,int x){
	if (x > tree[v].c){
		ans = -1;
		return;
	}
	if (tree[v].b==tree[v].e){
		tree[v].c -= x;
		ans = tree[v].b;
		return;
	}
	if (x <= tree[2 * v + 1].c)
		Insert(2 * v + 1, x);
	else
		Insert(2 * v + 2, x);
	tree[v].c = max(tree[2 * v + 1].c, tree[2 * v + 2].c);
}
int main(){
	int x;
	while (~scanf("%d%d%d", &h, &w, &n)){
		int len = min(h, n);
		Create(0, 1, len);
		for (int i = 0; i < n; i++){
			scanf("%d",&x);
			Insert(0, x);
			printf("%d\n", ans);
		}
	}
	return 0;
}

  

时间: 2025-01-02 14:56:09

HUD2795 线段树(单点更新)的相关文章

POJ训练计划2828_Buy Tickets(线段树/单点更新)

解题报告 题意: 插队完的顺序. 思路: 倒着处理数据,第i个人占据第j=pos[i]+1个的空位. 线段树维护区间空位信息. #include <iostream> #include <cstdio> #include <cstring> using namespace std; struct node { int x,v; } num[201000]; int sum[1000000],ans[201000]; void cbtree(int rt,int l,in

HDU2852_KiKi&#39;s K-Number(线段树/单点更新)

解题报告 题目传送门 题意: 意思很好理解. 思路: 每次操作是100000次,数据大小100000,又是多组输入.普通模拟肯定不行. 线段树结点记录区间里存在数字的个数,加点删点操作就让该点个数+1,判断x存在就查询[1,x]区间的个数和[1,x-1]的个数. 求x之后第k大的数就先确定小于x的个数t,第t+k小的数就是要求的. #include <iostream> #include <cstdio> #include <cstring> using namespa

POJ3264_Balanced Lineup(线段树/单点更新)

解题报告 题意: 求区间内最大值和最小值的差值. 思路: 裸线段树,我的线段树第一发.区间最值. #include <iostream> #include <cstring> #include <cstdio> #define inf 99999999 #define LL long long using namespace std; LL minn[201000],maxx[201000]; void update(LL root,LL l,LL r,LL p,LL

HDU1166_敌兵布阵(线段树/单点更新)

解题报告 题意: 略 思路: 线段树单点增减和区间求和. #include <iostream> #include <cstring> #include <cstdio> #define LL long long using namespace std; int sum[201000]; void update(int root,int l,int r,int p,int v) { int mid=(l+r)/2; if(l==r)sum[root]+=v; else

HDU1754_I Hate It(线段树/单点更新)

解题报告 题意: 略 思路: 单点替换,区间最值 #include <iostream> #include <cstring> #include <cstdio> #define inf 99999999 using namespace std; int maxx[808000]; void update(int root,int l,int r,int p,int v) { int mid=(l+r)/2; if(l==r)maxx[root]=v; else if(

Uva 12299 RMQ with Shifts(线段树 + 单点更新 )

Uva 12299 RMQ with Shifts (线段树 + 单点更新) 题意: 对于给定的序列 x[i]给出一个操作 shift(a,b,c,d,e) 对应的是将 x[a]与x[b] x[b]与x[c] 这样相邻的两两交换For example, if A={6, 2, 4, 8, 5, 1, 4}then shift(2, 4, 5, 7) yields {6, 8, 4, 5, 4, 1, 2}. After that,shift(1, 2) yields {8, 6, 4, 5, 4

POJ2352_Stars(线段树/单点更新)

解题报告 题意: 坐标系中,求每颗星星的左下角有多少星星. 思路: 把横坐标看成区间,已知输入是先对y排序再对x排序,每次加一个点先查询该点x坐标的左端有多少点,再更新点. #include <iostream> #include <cstdio> #include <cstring> using namespace std; int sum[200000]; struct node { int x,y; } p[20000]; void push_up(int roo

HDU 1754 I Hate It (线段树 单点更新)

题目链接 中文题意,与上题类似. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 #include <cstdlib> 6 #include <algorithm> 7 const int maxn = 200000+10; 8 using namespace std; 9 int a[maxn], n, m; 10

HDU 1166 敌兵布阵(线段树单点更新,板子题)

敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 87684    Accepted Submission(s): 36912 Problem Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务

Minimum Inversion Number(线段树单点更新+逆序数)

Minimum Inversion Number(线段树单点更新+逆序数) Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that satisfy