目录

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;
}