Contest1816 - 2019年我能变强组队训练赛第九场 G Lexical Sign Sequence 贪心+树状数组

问题 G: Lexical Sign Sequence

时间限制: 1 Sec  内存限制: 128 MB
[提交] [状态] [命题人:admin]

题目描述

Andi likes numbers and sequences, especially, sign sequences. A sign sequence is a sequence which consists of -1 and 1. Andi is a curious person, thus, he wants to build a sign sequence which length is N (the positions are numbered from 1 to N, inclusive).
However, Andi also likes some challenges. Therefore, he prefilled some positions in the sequence with -1 or 1 (the number in these positions cannot be changed). Andi also wants the sequence to fulfill K constraints.
For each constraint, there are 3 numbers: Ai, Bi, and Ci. This means that the sum of numbers which position is in the range [Ai,Bi] (inclusive) must be at least Ci.
Sounds confusing, right? It is not done yet. Since there can be many sequences that fulfill all the criteria above, Andi wants the sequence to be lexicographically smallest. Sequence X is lexicographically smaller than sequence Y if and only if there exists a position i where Xi < Yi and Xj = Yj for all j < i.
Find the sequence Andi wants.

 

输入

Input begins with a line containing two integers: N K (1≤N≤100000; 0≤K≤100000) representing the length of the sequence and the number of constraints, respectively. The second line contains N integers: Pi (-1≤Pi≤1). If Pi = 0, then the ith position in the sequence is not prefilled, otherwise the ith position in the sequence is prefilled by Pi. The next K lines, each contains three integers: Ai Bi Ci (1≤Ai≤Bi≤N;-N≤Ci≤N) representing the ith constraint.

 

输出

Output contains N integers (each separated by a single space) in a line representing the sequence that Andi wants if there exists such sequence, or “Impossible” (without quotes) otherwise.

 

样例输入

复制样例数据

3 2
0 0 0
1 2 2
2 3 -1

样例输出

1 1 -1

题解:未能确定的 都先设置成-1,对于一个区间,如果不符合当然要从r向前一个一个变为1,对于两个区间,那就是r小的先操作

#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 10;
#define lowbit(x) (x & (-x))

int sum[N];
int n, k;
int a[N];
set<int> s;
struct node {
	int A, B, C;
	bool operator <(const node &b) {
		if(B != b.B) return B < b.B;
		else return A < b.A;
	}
}b[N]; 
void update(int pos, int val) {
	while(pos <= N) {
		sum[pos] += val;
		pos += lowbit(pos);
	}
}
int query(int pos) {
	int res = 0;
	while(pos) {
		res += sum[pos];
		pos -= lowbit(pos);
	}
	return res;
}
int main() {
	scanf("%d %d", &n, &k);
	for(int i = 1; i <= n; i++) {
		scanf("%d", &a[i]);
		if(a[i] == 0) {
			a[i] = -1;	
			s.insert(-i);
		}
		update(i, a[i]);
	}
	for(int i = 1; i <= k; i++)
		scanf("%d %d %d", &b[i].A, &b[i].B, &b[i].C);
	sort(b + 1, b + 1 + k);
	int flag = 1;
	int cnt, pos;
	set<int>::iterator it;
	for(int i = 1; i <= k; i++) {
		cnt = query(b[i].B) - query(b[i].A - 1);
		if(cnt >= b[i].C) continue;
	//	cout << cnt << endl;
		while(cnt < b[i].C && s.size()) {
			it = s.lower_bound(-b[i].B);
			if(it == s.end()) break;
			pos = -(*it);
			if(pos < b[i].A) break;
			
			a[pos] = 1;
	//		cout << (pos) << endl;
			update(pos, 2);
			cnt += 2;
			s.erase(it);
		}
		if(cnt < b[i].C) {
			printf("Impossible\n");
			return 0;
		}
	}
	for(int i = 1; i <= n; i++)
		printf("%d%c", a[i], " \n"[i == n]);
	return 0;
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值