【bzoj1604】[Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 旋转坐标系+并查集+Treap/STL-set
题目描述
输入
第1行输入N和C,之后N行每行输入一只奶牛的坐标.
输出
仅一行,先输出牛群数,再输出最大牛群里的牛数,用空格隔开.
样例输入
4 2
1 1
3 3
2 2
10 10
样例输出
2 3
题解
为了练习Treap找到的这道略神的题
首先直接处理曼哈顿距离不是特别容易,我们可以把所有的点绕着原点逆时针旋转45°,这样原来的点$(x,y)$就变为了$(\frac{x-y}{\sqrt 2},\frac{x+y}{\sqrt 2})$,查询的区域变为了矩形范围,切比雪夫距离(横纵坐标差的绝对值最大值)不超过$\frac c{\sqrt 2}$。
然后约掉$\frac 1{\sqrt 2}$,就变为普通的矩形区域查询问题。
先将所有变换后的点按照横坐标排序,然后从左往右扫,将左面横坐标不满足条件的点删除。然后考虑连边:我们没有必要将所有在范围之内的点与当前点连边,只需要将当前点与第一个纵坐标比它大的点、第一个纵坐标比它小的点,如果满足条件就连边。
证明:使用数学归纳法
两个点之间使用这种方法是一定能够连上的。
如果k个点连上了,且纵坐标都比当前点大,并且横坐标满足条件,如果这种方法是不成立的,那么不妨设y1、y2,其中y1为纵坐标最接近当前点,y2为要连的点,我们要证的就是“当前点与y2有边,与y1没有边”是假命题。证明显然~
纵坐标比当前点小的时候同理。
于是k+1个点也能连上。命题得证。
回到题中,删点加点、查询前驱后继可以使用平衡树,维护连通性可以使用并查集。最后扫一遍每个点即可得到答案。
时间复杂度$O(n\log n)$。
事实上,STL的set比Treap还快~
Treap:
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#define N 100010
using namespace std;
struct data
{
int x , y;
}a[N];
typedef pair<int , int> pr;
int l[N] , r[N] , rnd[N] , tot , root , f[N] , tmp , num[N];
pr w[N];
bool cmp(data a , data b)
{
return a.x < b.x;
}
void zig(int &k)
{
int t = l[k];
l[k] = r[t] , r[t] = k , k = t;
}
void zag(int &k)
{
int t = r[k];
r[k] = l[t] , l[t] = k , k = t;
}
void insert(int &k , pr x)
{
if(!k) k = ++tot , w[k] = x , rnd[k] = rand();
else if(x < w[k])
{
insert(l[k] , x);
if(rnd[l[k]] < rnd[k]) zig(k);
}
else
{
insert(r[k] , x);
if(rnd[r[k]] < rnd[k]) zag(k);
}
}
void del(int &k , pr x)
{
if(x == w[k])
{
if(!l[k] || !r[k]) k = l[k] + r[k];
else if(rnd[l[k]] < rnd[k]) zig(k) , del(r[k] , x);
else zag(k) , del(l[k] , x);
}
else if(x < w[k]) del(l[k] , x);
else del(r[k] , x);
}
void pre(int k , pr x)
{
if(!k) return;
else if(x < w[k]) pre(l[k] , x);
else tmp = w[k].second , pre(r[k] , x);
}
void sub(int k , pr x)
{
if(!k) return;
else if(x < w[k]) tmp = w[k].second , sub(l[k] , x);
else sub(r[k] , x);
}
int find(int x)
{
return x == f[x] ? x : f[x] = find(f[x]);
}
int main()
{
int n , c , i , u , v , p = 1 , ans = 0 , mx = 0;
scanf("%d%d" , &n , &c);
for(i = 1 ; i <= n ; i ++ ) scanf("%d%d" , &u , &v) , a[i].x = u - v , a[i].y = u + v , f[i] = i;
sort(a + 1 , a + n + 1 , cmp);
for(i = 1 ; i <= n ; i ++ )
{
while(p < i && a[i].x - a[p].x > c) del(root , pr(a[p].y , p)) , p ++ ;
tmp = 0 , pre(root , pr(a[i].y , i));
if(tmp && a[i].y - a[tmp].y <= c) f[find(i)] = find(tmp);
tmp = 0 , sub(root , pr(a[i].y , i));
if(tmp && a[tmp].y - a[i].y <= c) f[find(i)] = find(tmp);
insert(root , pr(a[i].y , i));
}
for(i = 1 ; i <= n ; i ++ ) num[find(i)] ++ ;
for(i = 1 ; i <= n ; i ++ )
if(num[i])
ans ++ , mx = max(mx , num[i]);
printf("%d %d\n" , ans , mx);
return 0;
}
STL-set:
#include <cstdio>
#include <algorithm>
#include <set>
#define N 100010
using namespace std;
struct data
{
int x , y;
}a[N];
typedef pair<int , int> pr;
set<pr> s;
set<pr>::iterator it;
int f[N] , num[N];
bool cmp(data a , data b)
{
return a.x < b.x;
}
int find(int x)
{
return x == f[x] ? x : f[x] = find(f[x]);
}
int main()
{
int n , c , i , u , v , p = 1 , ans = 0 , mx = 0;
scanf("%d%d" , &n , &c);
for(i = 1 ; i <= n ; i ++ ) scanf("%d%d" , &u , &v) , a[i].x = u - v , a[i].y = u + v , f[i] = i;
sort(a + 1 , a + n + 1 , cmp);
for(i = 1 ; i <= n ; i ++ )
{
while(p < i && a[i].x - a[p].x > c) s.erase(pr(a[p].y , p)) , p ++ ;
it = s.upper_bound(pr(a[i].y , i));
if(it != s.end() && it->first - a[i].y <= c) f[find(i)] = find(it->second);
if(it != s.begin() && a[i].y - (--it)->first <= c) f[find(i)] = find(it->second);
s.insert(pr(a[i].y , i));
}
for(i = 1 ; i <= n ; i ++ ) num[find(i)] ++ ;
for(i = 1 ; i <= n ; i ++ )
if(num[i])
ans ++ , mx = max(mx , num[i]);
printf("%d %d\n" , ans , mx);
return 0;
}
【bzoj1604】[Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 旋转坐标系+并查集+Treap/STL-set的更多相关文章
- bzoj 1604 [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居(set+并查集)
Description 了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000)只奶牛,你会发现她们已经结成了几个“群”.每只奶牛在吃草的 时候有一个独一无二的位置坐标Xi,Yi( ...
- 【BZOJ】1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居(set+并查集+特殊的技巧)
http://www.lydsy.com/JudgeOnline/problem.php?id=1604 这题太神了... 简直就是 神思想+神做法+神stl.. 被stl整的我想cry...首先,, ...
- [BZOJ1604][Usaco2008 Open]Cow Neighborhoods 奶牛的邻居
[BZOJ1604][Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 试题描述 了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000)只奶牛,你会发 ...
- [BZOJ1604] [Usaco2008 Open] Cow Neighborhoods 奶牛的邻居 (queue & set)
Description 了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000)只奶牛,你会发现她们已经结成了几个“群”.每只奶牛在吃草的时候有一个独一无二的位置坐标Xi,Yi(l ...
- [BZOJ1604][Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 (Treap+单调队列)
题面 了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000)只奶牛,你会发现她们已经结成了几个"群".每只奶牛在吃草的时候有一个独一无二的位置坐标Xi,Yi( ...
- [BZOJ1604] [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居(好题)
传送门 良心题解 #include <set> #include <cstdio> #include <iostream> #include <algorit ...
- 【BZOJ1604】[Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 Treap+并查集
[BZOJ1604][Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 Description 了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000) ...
- BZOJ 1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居
题目 1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 Time Limit: 5 Sec Memory Limit: 64 MB Description ...
- BZOJ1604 & 洛谷2906:[USACO2008 OPEN]Cow Neighborhoods 奶牛的邻居——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=1604 https://www.luogu.org/problemnew/show/P2906#sub ...
随机推荐
- Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例
Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例 本文由 TonySpark 翻译自 Javarevisited.转载请参见文章末尾的要求. Java.util.concurr ...
- 在一个另一个文件中 #include一个**dlg.h文件,会发生dlg的资源ID未定义的错误 :
1 在一个另一个文件中 #include一个**dlg.h文件,会发生dlg的资源ID未定义的错误 : dlg1.h(23) : error C2065: 'IDD_DIALOG1' : und ...
- 【UML】活动图Activity diagram(转)
前言 在UML状态图的总结中说道,活动图和状态图是紧密相关的.它与流程图也有很多相似的地方. 定义 活动图是状态图的一种特殊形式.其中所有或多数状态都是活动状态,而且所有或多数转移都在源状态中的活动完 ...
- C#算术运算符
一.C#算术运算符 C#语言的算术运算符主要用于数学计算中. 二.示例 using System;using System.Collections.Generic;using System.Linq; ...
- 关于UINavigationController的一些技巧
未自定义任何东西的导航条效果如下: 1.自定义了 leftBarButtonItem 之后,左滑返回手势失效了,解决办法: self.navigationController.interactiveP ...
- 洛谷 P2735 电网
https://www.luogu.org/problemnew/show/P2735 定理什么的最讨厌了,匹克定理?不会,也不想学. 粉色的为电网,将图中的电网我们将他构造一个矩形,然后蓝色和绿色的 ...
- 浅谈 MySQL 中优化 SQL 语句查询常用的 30 种方法
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索 ...
- 使用apache benchmark(ab) 测试报错: apr_socket_recv: Connection timed out (110)
使用ab( apache benchmark )测试的时候,使用如下命令: ab -n 15000 -c 200 http://localhost/abc/abc.php 执行操作一定条数,或连续 ...
- 如何用纯 CSS 创作一组昂首阔步的圆点
效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/ejrMKe 可交互视频 ...
- 【nginx】nginx.sh nginx 安装脚本
#! /bin/shcd /usr/local/srcwget http://nginx.org/download/nginx-1.10.1.tar.gzecho 'download success' ...