バスと人CodeForces 160E次元部分配列セグメントツリー+

バスと人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;
} 

おすすめ

転載: www.cnblogs.com/alking1001/p/11440850.html