题意:链接

方法: Treap

解析:

前几道资格赛的题水的不行,这道Gold的题就够分量辣。

首先这个曼哈顿距离啥的肯定能做文章,怎么转化是个问题,自己玩了一会没玩出来,就查了查曼哈顿距离的转化,发现这个玩意转化之后就变得有思路多了,所以这数学本领还是非常重要啊=-=

先看曼哈顿距离的定义

|x1−x2|+|y1−y2|

拆绝对值

x1−x2+y1−y2或x1−x2+y2−y1

x2−x1+y1−y2或x2−x1+y2−y1

即|x1+y1−(x2+y2)|或|x1−y1−(x2−y2)|

设x1+y1为x′,x1−y1为y′

则|x1′−x2′|或|y1′−y2′|

所以原要求1转化为

max(|x1′−x2′|,|y1′−y2′|)<=c

这样的二维的东西显然排序一下降一维。

按x’排序后。维护一个x’的队列,再对y’维护一个平衡树即可了。

至于要求2,即是并查集,也就是说平衡树每一次拿出来前驱后继维护下并查集即可。

y’显然可能反复,又维护并查集我们须要拿出来标号。所以平衡树须要多维护一个no,所以再删除的时候我们要找到v与no都跟要删除的目标节点同样的节点删除。

(前驱写挫WA一次= =!

代码:

#include <ctime>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 100010
using namespace std;
int fa[N];
int q[N];
int tot;
int root;
int cnt[N];
struct node
{
int l,r,w,v,no,rnd,siz;
}tr[N];
void pushup(int rt)
{
tr[rt].siz=tr[tr[rt].l].siz+tr[tr[rt].r].siz+tr[rt].w;
}
void rturn(int &rt)
{
int t=tr[rt].l;
tr[rt].l=tr[t].r;
tr[t].r=rt;
tr[t].siz=tr[rt].siz;
pushup(rt);
rt=t;
}
void lturn(int &rt)
{
int t=tr[rt].r;
tr[rt].r=tr[t].l;
tr[t].l=rt;
tr[t].siz=tr[rt].siz;
pushup(rt);
rt=t;
}
void insert(int &rt,int v,int no)
{
if(!rt)
{
rt=++tot;
tr[rt].siz=1,tr[rt].no=no,tr[rt].rnd=rand();
tr[rt].v=v,tr[rt].w=1;
return;
}
tr[rt].siz++;
if(v<=tr[rt].v)
{
insert(tr[rt].l,v,no);
if(tr[tr[rt].l].rnd<tr[rt].rnd)rturn(rt);
}else
{
insert(tr[rt].r,v,no);
if(tr[tr[rt].r].rnd<tr[rt].rnd)lturn(rt);
}
}
void del(int &rt,int v,int no)
{
if(!rt)return;
tr[rt].siz--;
if(tr[rt].v==v&&tr[rt].no==no)
{
if(tr[rt].l*tr[rt].r==0){rt=tr[rt].l+tr[rt].r;return;}
else
{
if(tr[tr[rt].l].rnd<tr[tr[rt].r].rnd)
{
rturn(rt);
del(rt,v,no);
}else
{
lturn(rt);
del(rt,v,no);
}
}
}else if(v<tr[rt].v)
{
del(tr[rt].l,v,no);
}else del(tr[rt].r,v,no);
}
int ans;
void q_pre(int rt,int v)
{
if(!rt)return;
if(v>=tr[rt].v)
{
ans=rt;
q_pre(tr[rt].r,v);
}else q_pre(tr[rt].l,v);
}
void q_sub(int rt,int v)
{
if(!rt)return;
if(v<tr[rt].v)
{
ans=rt;
q_sub(tr[rt].l,v);
}else q_sub(tr[rt].r,v);
}
struct point
{
int x,y;
}pt[N];
int n,c;
int find(int x)
{
if(x!=fa[x])return fa[x]=find(fa[x]);
return x;
}
int cmp(point a,point b)
{
if(a.x==b.x)return a.y<b.y;
return a.x<b.x;
}
int main()
{
scanf("%d%d",&n,&c);
for(int i=1;i<=n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
pt[i].x=x+y,pt[i].y=x-y;
fa[i]=i;
}
sort(pt+1,pt+n+1,cmp);
int head=1,tail=0;
for(int i=1;i<=n;i++)
{
while(head<=tail&&pt[i].x-pt[q[head]].x>c)
{
del(root,pt[q[head]].y,q[head]);
head++;
}
ans=0;
q_pre(root,pt[i].y);
int tmp=ans;
if(tmp!=0)
{
if(pt[i].y-tr[tmp].v<=c)
{
if(find(i)!=find(tr[tmp].no))
{
fa[find(i)]=find(tr[tmp].no);
}
}
}
ans=0;
q_sub(root,pt[i].y);
tmp=ans;
if(tmp!=0)
{
if(tr[tmp].v-pt[i].y<=c)
{
if(find(i)!=find(tr[tmp].no))
{
fa[find(i)]=find(tr[tmp].no);
}
}
}
insert(root,pt[i].y,i);
q[++tail]=i;
}
int ma=0,print=0;
for(int i=1;i<=n;i++)
{
int fx=find(i);
if(!cnt[fx])
{
print++;
}
cnt[fx]++;
if(cnt[fx]>ma)ma=cnt[fx];
}
printf("%d %d\n",print,ma);
}

BZOJ 1604 [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 Treap的更多相关文章

  1. BZOJ 1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居

    题目 1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 Time Limit: 5 Sec  Memory Limit: 64 MB Description ...

  2. bzoj 1604 [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居(set+并查集)

    Description 了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000)只奶牛,你会发现她们已经结成了几个“群”.每只奶牛在吃草的 时候有一个独一无二的位置坐标Xi,Yi( ...

  3. bzoj 1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居——排序+贪心+set

    Description 了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000)只奶牛,你会发现她们已经结成了几个“群”.每只奶牛在吃草的时候有一个独一无二的位置坐标Xi,Yi(l ...

  4. BZOJ 1604 [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居:队列 + multiset + 并查集【曼哈顿距离变形】

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1604 题意: 平面直角坐标系中,有n个点(n <= 100000,坐标范围10^9) ...

  5. bzoj 1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 曼哈顿生成树

    大致题意:统计平面上由曼哈顿距离小于等于c的点对组成联通块的个数. 曼哈顿生成树的模板题.有关讲解:http://blog.csdn.net/acm_cxlove/article/details/88 ...

  6. bzoj 1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居【切比雪夫距离+并查集+multiset】

    参考:http://hzwer.com/4361.html 坐标开long long,inf开大点 先曼哈顿转切比雪夫(x+y,x-y),距离就变成了max(x',y'): 先按x排序,维护两个指针, ...

  7. 【BZOJ1604】[Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 Treap+并查集

    [BZOJ1604][Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 Description 了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000) ...

  8. 【BZOJ】1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居(set+并查集+特殊的技巧)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1604 这题太神了... 简直就是 神思想+神做法+神stl.. 被stl整的我想cry...首先,, ...

  9. 【BZOJ】1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居

    [算法]并查集+平衡树+数学+扫描线 [题解] 经典曼哈顿距离转切比雪夫距离. 曼哈顿距离:S=|x1-x2|+|y1-y2|<=c 即:max(x1-x2+y1-y2,x1-x2-y1+y2, ...

随机推荐

  1. mysql更改密码与远程管理

    set password = ': #在当前用户下更改密码 grant all privileges on *.* to root@"%" identified by " ...

  2. Linux学习之socket编程(二)

    Linux学习之socket编程(二) 1.C/S模型——UDP UDP处理模型 由于UDP不需要维护连接,程序逻辑简单了很多,但是UDP协议是不可靠的,实际上有很多保证通讯可靠性的机制需要在应用层实 ...

  3. 四 过滤模式 map Only - 作业完成 bloomFilter、top10、去重

    第四部分所有的模式涉及一个共同点: 不会改变原有的记录. 这些模式都是寻找数据子集的,不管结果集的规模是小(top10)还是大(像去重结果). 与第三部分差异是,他们通过对数据的相思子端坐概要与分组来 ...

  4. Watcher详解 工作机制, Watcher客户端注册、Watcher 服务端注册

    Watcher详解.接口 在 ZooKeeper 中, 接口类 Watcher 用于表示一个标注你的事件处理器,其定义了事件通知相关的逻辑,包含 KeeperState 和 EventType 两个枚 ...

  5. 【v2.x OGE教程 17】事务处理

    游戏代码中常常有些逻辑须要处理.因此OGE引擎加入了一个IUpdateHandler的类. IUpdateHandler类是OGE引擎中使用频率很之高的组件之中的一个,其本身是一个接口.内部有onUp ...

  6. 从 dig(nslookup) bind —— windows 下的域名解析服务器信息的查看

    dig(domain information groper,之所以选择这三个词,在于这三个词的首字母构成的词 dig 也有探索挖掘的含义)本身是 Linux 下的查询 DNS 信息的工具,功能类似 n ...

  7. centos 6.5搭建Samba

    Samba共享服务器 先将selinux关闭和防火墙端口号打开 #iptables -A INPUT -p udp -dport -j ACCEPT #iptables -A INPUT -p udp ...

  8. mysql日期函数及批量循环返回主键ID

    实际项目中总是会遇到各种时间计算查询等等许多时候是特别麻烦前阵子公司有个需求大致是要查询当前日期与数据库存储日期之差,本来写了个工具类调用的但是最后觉得这样不好就想着能不能用函数解决,没想到还真有这里 ...

  9. HDU 4349 Xiao Ming's Hope 组合数学

    题意:给你n,问在C(n,1),C(n,2)...C(n,n)中有多少个奇数. 比赛的时候打表看出规律,这里给一个数学上的说明. Lucas定理:A,B非负整数,p是质数,A,B化为p进制分别为a[n ...

  10. 手动删除oracle数据库

    --===================== -- 手动删除oracle数据库 --===================== 杀掉进程用此方法比较好,能保证杀得干净,而不是用sql 里面的语句ki ...