#include #include #include using namespace std; long long A, B; vector x; struct UnionFind{ vector par;//親(根) vector rank;//木の深さ //UnionFind(int n) { init(n); }; void init(int n){//初期化関数 par.resize(n); rank.resize(n); for(int i = 0; i < n; i++){ par[i] = i;//初めはノード一個の木なので根は自身 rank[i] = 1; } } int root(int x){//木の根を求める if(par[x] == x) return x; else return par[x] = root(par[x]); } bool same(int x, int y){//同じ木かどうか判定 return root(x) == root(y);//同じ木ならtrue } void unite(int x, int y){ x = root(x); y = root(y); if(x == y) return;//もし同じ木に属していたら何もしない if(rank[x] < rank[y]) swap(x, y);//数が大きい方に小さい方を結合させる par[y] = x; rank[x] += rank[y];//深さが同じ時だけ結合後深さが増える } int size(int x) {//深さを返す関数 return rank[root(x)]; } }; int main(){ long long N; cin >> N >> A >> B; x.resize(N); UnionFind U; U.init(N); for(int i = 0; i < N; i++){ cin >> x[i]; } for(int i = 0; i < N; i++){ int ze = lower_bound(x.begin(), x.end(), x[i] + A) - x.begin(); int g = upper_bound(x.begin(), x.end(), x[i] + B) - x.begin(); for(int j = ze; j < g; j++){ if(U.size(i) != 1){ U.unite(i, j); break; } U.unite(i, j); } } for(int i = 0; i < N; i++){ cout << U.size(i) << endl; } }