【PGBATTLE2019_せんべい4】みんみんみん

[Q] https://products.sint.co.jp/q_list

1. xでsort
2. y以下の中からzの最小値を出す。zminがクエリのzを下回るならok。
3. マッピング。seg[y] = zを記録しておく。
座標圧縮+セグ木でした。

・xが同じ値の場合の処理に注意。
1 1 1
1 2 3
があったとして、1 1 1を判定し、1 1 1をマッピングすると、1 2 3の判定でokが出てしまう。

対策:yを反転させてsort
1 -1 1
1 -2 3
走査時に復元し 1 2 3 -> 1 1 1 の処理をすると、妨害を防げる。

Q. tuple<ll, ll, ll, ll> をどうとりだすの?
A. c++17構造体束縛を利用できる。

・init
 vector<tuple<ll, ll, ll, ll>> T(N);
 rep(i, N){
   ll x, y, z;
   cin >> x >> y >> z;
   T[i] = {x, -y, z, i};
 }

 sort(all(T));
 map<ll, ll> mp;


・取り出し
 rep(i, N){
   auto&[a, b, c, d] = T[i];
   mp[-b] = 0;
   mp[c] = 0;
 }

実装

class RangeMin{
public:
 ll size_ = 1;
 vector<ll> dat;
 void init(ll sz){
   while (size_ <= sz) size_ *= 2;
   dat.resize(size_ * 2, oo);
 }
 void update(ll pos, ll x){
   pos += size_;
   if (!chmin(dat[pos], x))
     return ;
   while (pos >= 2){
     pos >>= 1;
     dat[pos] = min(dat[pos * 2], dat[pos * 2 + 1]);
   }
 }
 
 ll query_(ll l, ll r, ll k, ll a, ll b){
   if (r <= a || b <= l) return oo;
   if (l <= a && b <= r) return dat[k];
   ll v1 = query_(l, r, k*2, a, (a+b)>>1);
   ll v2 = query_(l, r, k*2+1, (a+b)>>1, b);
   return min(v1, v2);
 }
 
 ll query(ll l, ll r){
   return query_(l, r, 1, 0, size_);
 }
 
 ll getval(ll id){
   id += size_;
   return (dat[id]);
 }
};

int main(){
 cincout();

 ll N;
 cin >> N;
 vector<tuple<ll, ll, ll, ll>> T(N);
 rep(i, N){
   ll x, y, z;
   cin >> x >> y >> z;
   T[i] = {x, -y, z, i};
 }
 sort(all(T));
 map<ll, ll> mp;
 rep(i, N){
   auto&[a, b, c, d] = T[i];
   mp[-b] = 0;
   mp[c] = 0;
 }
 ll id=0;
 for(auto m:mp)mp[m.first] = ++id;
 rep(i, N){
   auto&[a, b, c, d] = T[i];
   b = mp[-b];
   c = mp[c];
 }

 bool ans[N] = {};
 RangeMin Z;
 Z.init(N*2+10);
 ll &pre = get<0>(T[0]);
 queue<pair<ll, ll>> Q;
 rep(i, N){
   auto&[a, b, c, id] = T[i];
   ll high = Z.query(0, b);
   if (high < c) ans[id] = true;
   Z.update(b, c); // id, val
 }
 rep(i, N){
   if (ans[i]) cout << "Yes" << endl;
   else cout << "No" << endl;
 }
}


この記事が気に入ったらサポートをしてみませんか?