G - 01Sequence Editorial by kusano
\(A_i\) を \(0\) で初期化し、\(R_i\) の小さな順に条件を満たしていきます。
\(i\) 番目の条件を処理する時点で、\(L_i\) から \(R_i\) の区間に含まれる \(0\) の個数 \(n\) が \(X_i\) 個未満ならば、\(X_i-n\) 個の \(0\) を \(1\) に変える必要があります。このとき、\(R_i\) 以下で最大の位置を書き換えるのが最善です。
\(L_i\) から \(R_i\) の区間に含まれる \(0\) の個数は、Fenwick Treeによって \(O(\log n)\)で数えることができます。書き換える場所については、 \(R_i\) 以下の位置をスタックに入れていけば良いです。
実行時間は遅くなりますが、Segtreeを使うと考えることが減って楽かもしれません。
C++での実装例(Fenwick Treeとキュー):
#include <iostream>
#include <vector>
#include <algorithm>
#include <atcoder/fenwicktree.hpp>
using namespace std;
int main()
{
int N, M;
cin>>N>>M;
vector<int> L(M), R(M), X(M);
for (int i=0; i<M; i++)
{
cin>>L[i]>>R[i]>>X[i];
L[i]--;
}
vector<int> I(M);
for (int i=0; i<M; i++)
I.push_back(i);
sort(I.begin(), I.end(), [&](int x, int y){return R[x]<R[y];});
vector<int> A(N);
atcoder::fenwick_tree<int> FT(N);
// 1を書き込める位置
vector<int> Q;
// Qに未追加の最小の位置
int q = 0;
for (int i: I)
{
for (; q<R[i]; q++)
Q.push_back(q);
// 書き込まなければならない1の個数
int n = X[i]-FT.sum(L[i], R[i]);
for (int j=0; j<n; j++)
{
int p = Q.back();
Q.pop_back();
A[p] = 1;
FT.add(p, 1);
}
}
for (int i=0; i<N; i++)
cout<<(i==0 ? "" : " ")<<A[i];
cout<<endl;
}
C++での実装例(Segtree):
#include <iostream>
#include <vector>
#include <algorithm>
#include <atcoder/segtree.hpp>
using namespace std;
int op_add(int a, int b) {return a+b;}
int op_max(int a, int b) {return max(a, b);}
int e_0() {return 0;}
int e_m1() {return -1;}
int main()
{
int N, M;
cin>>N>>M;
vector<int> L(M), R(M), X(M);
for (int i=0; i<M; i++)
{
cin>>L[i]>>R[i]>>X[i];
L[i]--;
}
vector<int> I(M);
for (int i=0; i<M; i++)
I.push_back(i);
sort(I.begin(), I.end(), [&](int x, int y){return R[x]<R[y];});
vector<int> A(N);
atcoder::segtree<int, op_add, e_0> ST_sum(N);
atcoder::segtree<int, op_max, e_m1> ST_pos(N);
for (int i=0; i<N; i++)
ST_pos.set(i, i);
for (int i: I)
{
// 書き込まなければならない1の個数
int n = X[i]-ST_sum.prod(L[i], R[i]);
for (int j=0; j<n; j++)
{
int p = ST_pos.prod(L[i], R[i]);
A[p] = 1;
ST_sum.set(p, 1);
ST_pos.set(p, -1);
}
}
for (int i=0; i<N; i++)
cout<<(i==0 ? "" : " ")<<A[i];
cout<<endl;
}
posted:
last update: