KY270 火车票订购

区间加减区间最大值模板
真牛啊,机试数据范围当acm题改,N诺原题不用线段树,纽克改的得线段树+离散化
ti

#include<bits/stdc++.h>

using namespace std;

#define MZX 1000010

int n, m;
int tree[MZX], lazy[MZX];
int a[MZX], b[MZX], k[MZX];

void build(){
	memset(tree, 0, sizeof tree);
	memset(lazy, 0, sizeof lazy);
	return ;
}

int lisan(int* a, int* b, int n){
	int len = 0, temp[MZX];
	for(int i = 0; i < n; i ++ ){
		temp[len ++ ] = a[i];
		temp[len ++ ] = b[i];
	}
	sort(temp, temp + len);
	len = unique(temp, temp + len) - temp;
	for(int i = 0; i < n; i ++ ){
		a[i] = lower_bound(temp, temp + len, a[i]) - temp;
		b[i] = lower_bound(temp, temp + len, b[i]) - temp;
	}
	return len;
}

void pushdown(int root){  //懒标记传递到下一层,因为每一层query都会pushdown,所以只用传递一层 
	if(lazy[root] == 0) return ;
	
	tree[root << 1] += lazy[root];
	tree[root << 1 | 1] += lazy[root];
	
	lazy[root << 1] += lazy[root];
	lazy[root << 1 | 1] += lazy[root];

	lazy[root] = 0;
	return ;
}

void pushup(int root){
	tree[root] = max(tree[root << 1], tree[root << 1 | 1]);
	return ;
}

void update(int a, int b, int k, int l, int r, int root){
	if(a <= l && r <= b){
		lazy[root] += k;
		tree[root] += k; 
		return ;
	}
	int mid = (l + r) >> 1;
	if(a <= mid) update(a, b, k, l, mid, root << 1);
	if(mid + 1 <= b) update(a, b, k, mid + 1, r, root << 1 | 1);
	pushup(root);
}

int query(int a, int b, int l, int r, int root){
	int ans = 0;
	if(a <= l && r <= b) return tree[root];
	pushdown(root);
	int mid = (l + r) >> 1;
	if(a <= mid) ans = max(ans, query(a, b, l, mid, root << 1));
	if(mid + 1 <= b) ans = max(ans, query(a, b, mid + 1, r, root << 1 | 1));
	return ans;
}

int main()
{
	while(cin>>n>>m){
		
		for(int i = 0; i < n; i ++ ) scanf("%d%d%d", &a[i], &b[i], &k[i]);
		build();
		int len = lisan(a, b, n);
		
		for(int i = 0; i < n; i ++ ){
			if(query(a[i], b[i], 0, len - 1, 1) + k[i] <= m){
				update(a[i], b[i], k[i], 0, len - 1, 1);
				printf("1\n");
			}
			else printf("0\n");
		}
	}
	return 0;
}

N诺版解法

#include<bits/stdc++.h>

using namespace std;

struct node{
	int id;
	int time;
	bool flag;
	int pum;
	bool operator < (const node &A) const{
		if(time != A.time) 
			return time < A.time;
		else
			return flag < A.flag;	
	}
}tam[10010]; 

int a, b;
int n, m;
int k;
int cntp;
vector<int>q;

int main() {
	while(cin>>n>>m){
		
		memset(tam, 0, sizeof tam);
		cntp = 0;
		while(q.size()) q.pop_back();
		
		for(int i = 0; i < n; i ++ ){
			cin>>a>>b>>k;
			tam[cntp].id = i;
			tam[cntp].flag = 1;
			tam[cntp].pum = k;
			tam[cntp ++ ].time = a;
			
			tam[cntp].id = i;
			tam[cntp].flag = 0;
			tam[cntp].pum = k;
			tam[cntp ++ ].time = b;			
		}
		
		sort(tam, tam + cntp);
		int np = 0;
		for(int i = 0; i < cntp; i ++ ){
			if(tam[i].flag == 1){  //如果是上车 
				//cout<<"***"<<endl; 
				if(np + tam[i].pum <= m){  //如果可以上车 
					np += tam[i].pum;
					q.push_back(tam[i].id);
					cout<<1<<endl;
				}
				else cout<<0<<endl;
			}
			else{  //下车 
				for(auto t = q.begin(); t != q.end(); t ++ ){
					if(*t == tam[i].id){
						np -= tam[i].pum;
						q.erase(t);
						break;
					}
				}
			}
		}
	}
    
    return 0;
}
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值