zoukankan      html  css  js  c++  java
  • POJ

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

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

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

    /*********************************************************
    *            ------------------                          *
    *   author AbyssalFish                                   *
    **********************************************************/
    #include<cstdio>
    #include<iostream>
    #include<string>
    #include<cstring>
    #include<queue>
    #include<vector>
    #include<stack>
    #include<vector>
    #include<map>
    #include<set>
    #include<algorithm>
    #include<cmath>
    #include<numeric>
    #include<cassert>
    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
    ", 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;
    }
  • 相关阅读:
    纠结我一上午的asp.net操作mysql问题
    C#术语【转自MSDN】
    asp.net新手必知必会——我们为什么要用asp.net
    图片在浏览器中底部对齐———解决方法之一
    asp.net做的网站比asp做的站慢?
    我是一个可悲的程序员
    今天离开职场去过自己的潇洒人生
    asp.net应用程序重新启动
    asp.net分页解决方法
    80. 删除有序数组中的重复项 II
  • 原文地址:https://www.cnblogs.com/jerryRey/p/5004597.html
Copyright © 2011-2022 走看看