目录
Description
有 \(m\) 个区间,给出每个区间的和,构造一个 \(01\) 字串
State
\(1<=n,m<=2*10^5\)
\(1<=l<=r<=n\)
\(1<=x<=r-l+1\)
Input
6 3
1 4 3
2 2 1
4 6 2
Output
0 1 1 1 0 1
Solution
要求 \(1\) 的个数尽可能小;
根据贪心,按 \(r\) 升序排列,然后每一个区间数一下现在是多少,从 \(r\) 开始填 \(1\) 就可以,在这里用一下并查集优化一下就可以防 \(T\) 了
Code
const int N = 2e5 + 5;
int n, m, _, k;
struct Node
{
int l, r, w;
void read(){ sddd(l, r, w); }
bool operator<(Node o){
if(r == o.r) return l < o.l;
return r < o.r;
}
} a[N];
int c[N];
void add(int x, int delta)
{
while(x < N){
c[x] += delta;
x += lowbit(x);
}
}
int ask(int x)
{
int ans = 0;
while(x){
ans += c[x];
x -= lowbit(x);
}
return ans;
}
int fa[N];
int Find(int x)
{
if(x == fa[x]) return x;
return fa[x] = Find(fa[x]);
}
signed main()
{
//IOS;
while(~ sdd(n, m)){
rep(i, 1, n) fa[i] = i;
rep(i, 1, m) a[i].read();
sort(a + 1, a + 1 + m);
rep(i, 1, m){
int l = a[i].l, r = a[i].r, w = a[i].w;
int res = ask(r) - ask(l - 1);
if(res < w){
int pos = Find(r);
while(res != w){
if(ask(pos) - ask(pos - 1) == 0){
add(pos, 1);
res ++;
}
pos = Find(pos - 1);
}
fa[r] = pos;
}
}
for(int i = 1; i <= n; i ++){
printf("%d ", ask(i) - ask(i - 1));
}
puts("");
}
//PAUSE;
return 0;
}