您的位置:首页 > 其它

hdu5107 K-short Problem 离线,离散化,线段树

2015-08-22 01:12 369 查看
题意:给出n栋楼的坐标和高度,询问<=x,<=y的第k高的楼的高度,(k<=10).

parse:离线处理,对y坐标离散化,把楼和询问按x排序,每询问到x将<=x的楼加入线段树中,线段树维护y坐标的前10,这时就可以查询1-y的第k高,二维转一维。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<ostream>
#include<istream>
#include<algorithm>
#include<queue>
#include<string>
#include<cmath>
#include<set>
#include<map>
#include<stack>
#include<vector>
#define fi first
#define se second
#define pii pair<int,int>
#define ll long long
#define inf 1000000009;
#define eps 1e-8
using namespace std;
const int maxn=30005;
int n,m;
struct Node
{
    int x,y,w;
    int id;
    bool operator<(const Node& u)const
    {
        if(x==u.x)
            return id<u.id;
        return x<u.x;
    }
};
Node d[maxn];
Node q[maxn];
int y[maxn*2];
int cnt;
int h[maxn<<3][15];
int we[maxn];
int e;
int ans[maxn];
void pushUp(int rt)
{
    int tmp[30];
    for(int i=1;i<=10;i++) {
        tmp[i]=h[rt<<1][i];
        tmp[i+10]=h[rt<<1|1][i];
    }
    sort(tmp+1,tmp+21);
    for(int i=1;i<=10;i++)
        h[rt][i]=tmp[i];
}
void update(int l,int a,int L,int R,int rt)
{
    if(l==L&&l==R) {
        for(int i=1;i<=10;i++) {
            if(a<h[rt][i]) {
                h[rt][i]=a;
                break;
            }
        }
        return;
    }
    int m=(L+R)/2;
    if(l<=m)
        update(l,a,L,m,rt<<1);
    else
        update(l,a,m+1,R,rt<<1|1);
    pushUp(rt);
}
void query(int l,int r,int k,int L,int R,int rt)
{
    if(l<=L&&r>=R) {
        for(int i=1;i<=k;i++) {
            we[e++]=h[rt][i];
        }
        return;
    }
    int m=(L+R)/2;
    if(l<=m)
        query(l,r,k,L,m,rt<<1);
    if(r>m)
        query(l,r,k,m+1,R,rt<<1|1);
}
int main()
{
    int a,b,c;
    while(~scanf("%d%d",&n,&m)) {
        for(int i=1;i<=(n+m)*4;i++) {
            for(int j=1;j<=10;j++)
                h[i][j]=inf;
        }
        cnt=0;
        for(int i=1;i<=n;i++) {
            scanf("%d%d%d",&d[i].x,&d[i].y,&d[i].w);
            d[i].id=i;
            y[cnt++]=d[i].y;
        }
        for(int i=1;i<=m;i++) {
            scanf("%d%d%d",&q[i].x,&q[i].y,&q[i].w);
            y[cnt++]=q[i].y;
            q[i].id=i;
        }
        sort(y,y+cnt);
        int k=unique(y,y+cnt)-y;
        for(int i=1;i<=n;i++) {
            d[i].y=lower_bound(y,y+k,d[i].y)-y+1;
        }
        for(int i=1;i<=m;i++) {
            q[i].y=lower_bound(y,y+k,q[i].y)-y+1;
        }
        sort(d+1,d+n+1);
        sort(q+1,q+m+1);
          int kk=1;
        for(int i=1;i<=m;i++) {
            while(kk<=n && d[kk].x<=q[i].x) {
                update(d[kk].y,d[kk].w,1,n+m,1);
                kk++;
            }
            e=0;
            query(1,q[i].y,q[i].w,1,n+m,1);
            sort(we,we+e);
            int op=we[q[i].w-1];
            if(op==1000000009)
                op=-1;
            ans[q[i].id]=op;
        }
        for(int i=1;i<=m;i++)
            printf("%d\n",ans[i]);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: