时间限制: 1 Sec 内存限制: 128 MB
题目描述
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
先把0全部变成-1,然后区间按照从后往前更新,区间内部从前往后吧能改为1的改到零界就可以了,用线段树维护区间,查询区间就可以了
#pragma GCC optimize(3,"Ofast","inline")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <queue>
#include <vector>
#include <map>
#include <cmath>
#include <stack>
#include <set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e5+10;
struct node
{
int l,r,val;
bool operator < (const node &a)const{
if(r==a.r) return l<a.l;
return r<a.r;
}
}q[maxn];
int ans[maxn];
int sum[maxn<<2];
bool flag[maxn];
void build(int rt,int l,int r){
if(l==r){
if(ans[l]==1){
sum[rt]=1;
}
else {
sum[rt]=-1;
}
return;
}
int mid=(l+r)>>1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void update(int rt,int l,int r,int p,int v){
if(l==r){
sum[rt]+=v;
return;
}
int mid=(l+r)>>1;
if(p<=mid)update(rt<<1,l,mid,p,v);
else update(rt<<1|1,mid+1,r,p,v);
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
int query(int rt,int l,int r,int x,int y){
if(x<=l&&r<=y){
return sum[rt];
}
int mid=(l+r)>>1;
if(y<=mid)return query(rt<<1,l,mid,x,y);
else if(x>mid)return query(rt<<1|1,mid+1,r,x,y);
else return query(rt<<1,l,mid,x,mid)+query(rt<<1|1,mid+1,r,mid+1,y);
}
int main()
{
int n,k;
scanf("%d %d",&n,&k);
for (int i = 1; i <=n ; ++i)
{
scanf("%d",ans+i);
if(!ans[i]){
ans[i]=-1;
flag[i]=true;
}
}
build(1,1,n);
//cout<<"build succes"<<endl;
for (int i = 1; i <= k; ++i){
scanf("%d %d %d",&q[i].l,&q[i].r,&q[i].val);
//cout<<q[i].l<<" "<<q[i].r<<" "<<q[i].val<<endl;
}
sort(q+1,q+1+k);
//cout<<"sort sucxes"<<endl;
bool fflag=false;
for(int i=1;i<=k;i++){
//cout<<"query start "<<q[i].l<<q[i].r<<endl;
int number=query(1,1,n,q[i].l,q[i].r);
//cout<<"query succes "<<number<<endl;
if(number>=q[i].val) continue;
int num=q[i].val-number;
int tmpl=q[i].l,tmpr=q[i].r;
while(num>0&&tmpl<=tmpr){
if(flag[tmpr]){
flag[tmpr]=false;
ans[tmpr]=1;
update(1,1,n,tmpr,2);
//cout<<"update succes"<<endl;
num-=2;
}
tmpr--;
}
if(num>0){
fflag=true;
break;
}
}
//cout<<"break"<<endl;
if(fflag) cout<<"Impossible"<<endl;
else{
for(int i=1;i<n;i++)
printf("%d ", ans[i]);
printf("%d\n", ans[n]);
}
return 0;
}