小鸟往四个方向飞都枚举一下,数据范围没给,离散以后按在其中一个轴线排序,在线段树上更新墙的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+;
int N, M;
int dist[MAX_N];
int fly_to[MAX_N];
int wall_cnt[MAX_N]; const int MAX_SIZE = MAX_N*;
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 = ; i < sz; i++){
r[i] = i;
}
fi = dat; //se = dat_;
sort(r,r+sz,cmp);
mp[a[r[]] = ] = dat[r[]];
for(int i = ; i < sz; i++){
int k = r[i], p = r[i-];
if(dat[k] != dat[p]){
mp[ a[k] = a[p]+ ] = dat[k];
}
else {
a[k] = a[p];
}
}
} void init()
{
// wall [0 N*2), bird [N*2, Ui)
sp = N*; dat_sz = sp+M;
for(int i = ; 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 = <<; 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] = -;
}
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^;
//trick 小鸟可能在墙的延迟线上,害得我WA了无数发 T_T
if((xs[k2] >= xs[k])){
qval = (k>>)+;
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<<]]), abs(pos_b - mpy[ys[w_id<<|]]) );
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 = ; qr = n0; qval = ;
update(); for(int i = ; i < dat_sz; i++){
sweep_line(ry[i],ys,xs,mpy);
} ql = ; qr = n0; qval = ;
update();
for(int i = dat_sz-; i >= ; 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-]]);
fly(rx,xs,ys,mpx,ys[ry[dat_sz-]]);
memset(wall_cnt,,sizeof(int)*N);
for(int i = ; i < M; i++) wall_cnt[fly_to[i]]++;
for(int i = ; 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 ;
}

POJ - 3470 Walls的更多相关文章

  1. POJ 3470 Walls(线段树+扫描线)

    [题目链接] http://poj.org/problem?id=3470 [题目大意] 给出几面墙,均垂直于x轴或者y轴,给出一些鸟的位置(二维坐标点), 鸟只会垂直x轴或者y轴飞行,并且会撞上最近 ...

  2. POJ 1161 Walls(最短路+枚举)

    POJ 1161 Walls(最短路+枚举) 题目背景 题目大意:题意是说有 n个小镇,他们两两之间可能存在一些墙(不是每两个都有),把整个二维平面分成多个区域,当然这些区域都是一些封闭的多边形(除了 ...

  3. POJ 1161 Walls【floyd 以面为点建图】

    题目链接:http://poj.org/problem?id=1161 题目大意: 1.给出m个区域,n个俱乐部点.接下来是n个俱乐部点以及各个区域由什么点围成.求一个区域到各个俱乐部点的距离之和最小 ...

  4. poj 1161 Walls

    https://vjudge.net/problem/POJ-1161 题意:有m个区域,n个小镇,有c个人在这些小镇中,他们要去某一个区域中聚会,从一个区域到另一个区域需要穿墙,问这些人聚到一起最少 ...

  5. POJ 1161 Walls(Floyd , 建图)

    题意: 给定n个城市, 然后城市之间会有长城相连, 长城之间会围成M个区域, 有L个vip(每个vip会处于一个城市里)要找一个区域聚会, 问一共最少跨越多少个长城. 分析: 其实这题难就难在建图, ...

  6. POJ 1161 Walls ( Floyd && 建图 )

    题意 :  在某国,城市之间建起了长城,每一条长城连接两座城市.每条长城互不相交.因此,从一个区域到另一个区域,需要经过一些城镇或者穿过一些长城.任意两个城市A和B之间最多只有一条长城,一端在A城市, ...

  7. Walls POJ 1161

    参考了大牛的博客 http://blog.csdn.net/wangjian8006/article/details/7958838 题目大意: 给出n个点,在这些点中有些点是俱乐部点,并且有m个区域 ...

  8. poj 1266 Cover an Arc.

    http://poj.org/problem?id=1266 Cover an Arc. Time Limit: 1000MS   Memory Limit: 10000K Total Submiss ...

  9. 【POJ】1556 The Doors(计算几何基础+spfa)

    http://poj.org/problem?id=1556 首先路径的每条线段一定是端点之间的连线.证明?这是个坑...反正我是随便画了一下图然后就写了.. 然后re是什么节奏?我记得我开够了啊.. ...

随机推荐

  1. python 基础及if while for语句

    #####变量######一.命名规则   1.正常命名  可以由字母,下划线和数字组成,不能以数字开头,不能和关键字重明   2.驼峰命名法    1)大驼峰:每一个单词的首字母都大写     Fi ...

  2. MessageFormat 格式化String

    public static String buildFailureString(AtomicInteger count, String cause) { return MessageFormat.fo ...

  3. 4.AOP

    1.代理模式 代理模式(Proxy Pattern)是GoF23种常用设计模式之一使用代理模式创建代理对象,让代理对象控制目标对象的访问,并且可以在不改变目标对象的情况下添加一些额外的功能包括静态代理 ...

  4. sql函数将1,2,3转换为表

    /****** Object: UserDefinedFunction [dbo].[splitstring_to_table] Script Date: 2017/7/11 9:35:58 **** ...

  5. Install ElasticSearch plugin for head

    git clone git://github.com/mobz/elasticsearch-head.git yum install git npm cd elasticsearch-head npm ...

  6. 信息领域热词分析系统--python切词

    利用python将标题切割成词语 import jieba #读取文件 f=open(r"F:\大数据\大作业\爬取到的数据\data1_xinxi.txt",'r') s=f.r ...

  7. spring AOP注解

    此段小代码演示了spring aop中@Around @Before @After三个注解的区别@Before是在所拦截方法执行之前执行一段逻辑.@After 是在所拦截方法执行之后执行一段逻辑.@A ...

  8. 垃圾收集GC

    一.引用计数法给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器为0的对象就是不能再被使用的.引用计数法实现简单,判定效率也很高,但是它很 ...

  9. Mac使用zsh导致maven命令无效的解决方案

    第一步: vim ~/.zshrc 第二步:在.zshrc末尾加上 source ~/.bash_profile: 保存推出了 第三步 source ~/.bash_profile

  10. 关于火狐不响应event.keyCode解决方法

    <body onkeydown="enterkey(event)"> <!-- 点击键盘即触发 enterkey函数 --> function enterk ...