POJ - 3470 Walls

小鸟往四个方向飞都枚举一下,数据范围没给,离散以后按在其中一个轴线排序,在线段树上更新墙的id,然后就是点查询在在哪个墙上了。

这题有个trick,因为数据范围没给我老以为是inf设置小了,WA了很多发。(距离可能比0x3f3f3f3f大

实现上,我是把鸟和墙的坐标放一起的,用下标来区别两者。

/*********************************************************
*            ------------------                          *
*   author AbyssalFish                                   *
**********************************************************/
#include
#include
#include<string>
#include
#include
#include
#include
#include
#include
#include<set>
#include
#include
#include
#include
using namespace std;

typedef long long ll;
const int MAX_N = 5e4+5;
int N, M;
int dist[MAX_N];
int fly_to[MAX_N];
int wall_cnt[MAX_N];

const int MAX_SIZE = MAX_N*3;
int x[MAX_SIZE], y[MAX_SIZE];
int rx[MAX_SIZE], ry[MAX_SIZE];
int xs[MAX_SIZE], ys[MAX_SIZE];//discrete data
int mpx[MAX_SIZE], mpy[MAX_SIZE];//用于离散idx访问原值
int sp, dat_sz;

int *fi;//, *se;
bool cmp(int a, int b)
{
    return fi[a] < fi[b];// || (fi[a] == fi[b] && se[a] < se[b]);
}

/*
parameter :
原始数据dat , 名次r ,size, 离散数据 a
*/

void compress(int *dat, int *r, int sz, int *a, int *mp)//int *dat_
{
    for(int i = 0; i < sz; i++){
        r[i] = i;
    }
    fi = dat; //se = dat_;
    sort(r,r+sz,cmp);
    mp[a[r[0]] = 1] = dat[r[0]];
    for(int i = 1; i < sz; i++){
        int k = r[i], p = r[i-1];
        if(dat[k] != dat[p]){
            mp[ a[k] = a[p]+1 ] = dat[k];
        }
        else {
            a[k] = a[p];
        }
    }
}



void init()
{
    // wall [0 N*2), bird [N*2, Ui)
    sp = N*2; dat_sz = sp+M;
    for(int i = 0; i < dat_sz; i++){
        scanf("%d%d", x+i, y+i);
    }
    compress(x, rx, dat_sz, xs, mpx);
    compress(y, ry, dat_sz, ys, mpy);
}


#define para int o = 1, int l = 1,int r = n0
#define Tvar int mid = (l+r)>>1, lc = (o<<1), rc = (o<<1|1);
#define lsn lc, l, mid
#define rsn rc, mid+1, r
#define insd ql<=l&&r<=qr
const int ST_SIZE = 1<<19;

int cv[ST_SIZE];
//完整覆盖,wall的idx , 不完整覆盖 -1,  完全无覆盖 0
int n0;
int qpos;

int query(para)
{
    if(~cv[o]) return cv[o];
    else {
        Tvar
        return qpos <= mid? query(lsn) : query(rsn);
    }
}

int ql, qr, qval;

void update(para)
{
    if(insd){
        cv[o] = qval;
    }
    else {
        Tvar
        if(~cv[o]) {
            cv[lc] = cv[rc] = cv[o];
            cv[o] = -1;
        }
        if(ql <= mid) update(lsn);
        if(qr > mid) update(rsn);
    }
}



void sweep_line(int k, int *ys, int *xs, int *mpy)
{
    if(k < sp){
        int k2 = k^1;
         //trick 小鸟可能在墙的延迟线上,害得我WA了无数发 T_T
        if((xs[k2] >= xs[k])){
            qval = (k>>1)+1;
            ql = xs[k]; qr = xs[k2];
            update();
        }
    }
    else {
        qpos = xs[k];
        int w_id = query();
        //assert(w_id != -1);
        if(w_id) {
            w_id--;
            int pos_b = mpy[ys[k]];
            int d = min( abs(pos_b - mpy[ys[w_id<<1]]), abs(pos_b - mpy[ys[w_id<<1|1]]) );
            k -= sp;
            if(d < dist[k]){
                dist[k] = d; fly_to[k] = w_id;
            }
        }
    }
}

void fly(int *ry, int *ys, int *xs, int *mpy, int mxx)
{
    n0 = mxx;
    ql = 1; qr = n0; qval = 0;
    update();

    for(int i = 0; i < dat_sz; i++){
        sweep_line(ry[i],ys,xs,mpy);
    }

    ql = 1; qr = n0; qval = 0;
    update();
    for(int i = dat_sz-1; i >= 0; i--){
        sweep_line(ry[i],ys,xs,mpy);
    }
}

void solve()
{
    //memset(ans,0x3f,sizeof(ll)*M);
    fill(dist, dist+M, 0x7fffffff);

    fly(ry,ys,xs,mpy,xs[rx[dat_sz-1]]);
    fly(rx,xs,ys,mpx,ys[ry[dat_sz-1]]);
    memset(wall_cnt,0,sizeof(int)*N);
    for(int i = 0; i < M; i++) wall_cnt[fly_to[i]]++;
    for(int i = 0; i < N; i++){
        printf("%d\n", wall_cnt[i]);
    }
}

//#define LOCAL
int main()
{
#ifdef LOCAL
    freopen("in.txt","r",stdin);
#endif
    //cout<<((int)ceil(log2(15e4))+1);
    while(~scanf("%d%d", &N, &M)){
        //assert(N<=MAX_N && M <= MAX_N);
        init();
        solve();
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/jerryRey/p/5004597.html

你可能感兴趣的:(ui)