バスと人CodeForces 160E次元部分配列セグメントツリー+
問題の意味
与えられたN個のトリプル(a、b、c)は、M既存のクエリは、B ' '<Aを満たすために求めて、(A 'B'、C')クエリ各トリプレットを与え<B、最小のCに対応するC「<Cタプル数。
問題解決のためのアイデア
三次元の半順序の問題は、問題の解決策を確認し、私は初めてです。
兄は、そう言うオリジナルのブログまず、オフライン処理のすべてのお問い合わせは、同じ、与えられたタプルが問い合わせタプルであるべき場合には、これらのN + Mタプルは、小さなソートによると到着します前に。すべてのタプルを求めていることを確認するためにご注文後、答えはタプルの与えられたタプルの前に現れなければなりません。Cが最低条件を満たすために必要とされるためには、Cにツリーラインを確立すべきです セグメントツリー確立動作のC離散化、(b、c)は、Cとの添え字、Bは重量です。最大値Bに維持セグメントツリーを、セグメントツリー半分に求められたとき。
コードの実装(コードは簡単です参照)
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=2e5+7;
struct node{
int st, ed, t, id;
bool friend operator < (node a, node b)
{
return a.st==b.st ? a.id < b.id : a.st < b.st;
}
}a[maxn];
vector<int> v;
int tot;
int maxx[maxn<<2], id[maxn<<2];
int ans[maxn>>1];
int n, m;
void update(int rt, int l, int r, int pos, int val, int ID)
{
if(l==r)
{
//if(maxx[rt] < val)
{
maxx[rt]=val;
id[rt]=ID;
}
return ;
}
int mid=(l+r)>>1;
if(pos<=mid)
update(rt<<1, l, mid, pos, val, ID);
else
update(rt<<1|1, mid+1, r, pos, val, ID);
maxx[rt]=max(maxx[rt<<1], maxx[rt<<1|1]);
}
int query(int rt, int l, int r, int x, int y, int val)
{
if(l==r) return id[rt];
int mid=(l+r)>>1;
int ret=-1;
if(y<=mid)
{
if(maxx[rt<<1] >= val) ret=query(rt<<1, l, mid, x, y, val);
}
else if(x > mid)
{
if(maxx[rt<<1|1] >= val) ret=query(rt<<1|1, mid+1, r, x, y, val);
}
else
{
if( maxx[rt<<1] >= val ) ret=query(rt<<1, l, mid, x, mid, val);
if(ret==-1 && maxx[rt<<1|1] >= val) ret=query(rt<<1|1, mid+1, r, mid+1, y, val);
}
return ret;
}
int main()
{
scanf("%d%d", &n, &m);
for(int i=1; i<=n+m; i++)
{
scanf("%d%d%d", &a[i].st, &a[i].ed, &a[i].t);
a[i].id=i;
v.push_back(a[i].t);
}
sort(v.begin() , v.end());
v.erase( unique(v.begin() , v.end() ), v.end() );
tot=v.size() ;
sort(a+1, a+n+m+1);
for(int i=1; i<=n+m; i++)
{
a[i].t = lower_bound(v.begin() , v.end() , a[i].t) - v.begin() +1;
}
for(int i=1; i<=n+m; i++)
{
if(a[i].id<=n)
update(1, 1, tot, a[i].t, a[i].ed, a[i].id);
else
ans[a[i].id - n]=query(1, 1, tot, a[i].t, tot, a[i].ed);
}
for(int i=1; i<=m; i++)
{
printf("%d ", ans[i]);
}
return 0;
}