题目大意:

在平面上,有 n 个水晶柱,每个水晶柱可以用一个点表示

如果 4 个水晶柱依次相连可以构成一个四边形,满足其两条对角线分别平行于 x 轴和 y 轴,并且对角线的交点位于四边形内部(不包括边界)

那么这 4 个水晶柱就可以建立一个结界

其中,对角线的交点称作这个结界的中心

例如下左图中,水晶柱 ABCD 可以建立一个结界,其中心为 O

人们会把祭坛修建在最多层结界的保护中

其中不同层的结界必须有共同的中心,这些结界的边界不能有任何公共点,并且中心处也不能有水晶柱

这里共同中心的结界数量叫做结界的层数

为了达成这个目的,人们要先利用现有的水晶柱建立若干个结界,然后在某些结界的中心建立祭坛

例如上右图中,黑色的点表示水晶柱(注意 P 和 O 点不是水晶柱)。祭坛的一个最佳位置为 O 点,可以建立在 3 层结界中,其结界的具体方案见下左

当然,建立祭坛的最佳位置不一定是唯一,在上右图中,O 点左侧 1 单位的点 P 也可以建立一个在 3 层结界中的祭坛,见下右图

 

现在人们想知道:祭坛最佳选址地点所在的结界层数以及祭坛最佳的选址地点共有多少个

思路:

首先可以二分一下答案

然后对于每一个满足条件的点在它的上下左右四个方向一定有至少mid个点

对于上下或者左右是否满足条件 可以直接求出这个区间

对于另一个方向 使用扫描线与树状数组维护

 #include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define inf 2139062143
#define ll long long
#define MAXN 100100
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-;ch=getchar();}
while(isdigit(ch)) {x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,up[MAXN],dn[MAXN],q[MAXN],cnt;
vector<int> vec[MAXN];
int c[MAXN],hsh[MAXN];
int lowbit(int x) {return x&(-x);}
void add(int x,int val) {for(int i=x;i<=n;i+=lowbit(i)) c[i]+=val;}
int query(int x) {int res=;for(int i=x;i;i-=lowbit(i)) res+=c[i];return res;}
int check(int x)
{
int res=,t;
memset(hsh,,sizeof(hsh));
memset(c,,sizeof(c));
memset(up,,sizeof(up));
memset(dn,,sizeof(dn));
for(int i=;i<=cnt;i++)
for(int j=;j<vec[q[i]].size();j++) dn[vec[q[i]][j]]++;
for(int k=;k<=cnt;k++)
{
t=q[k];
for(int i=;i<vec[t].size();i--)
{
dn[vec[t][i]]--;
if((dn[vec[t][i]]<x||up[vec[t][i]]<x)&&hsh[vec[t][i]])
hsh[vec[t][i]]=,add(vec[t][i],-);
}
if(x-<vec[t].size())
{
int l=vec[t][x-],r=vec[t].size()-x;
if(r<) goto ed;
r=vec[t][r];
if(r>&&l<=r-) res+=query(r-)-query(l);
}ed:;
for(int i=;i<vec[t].size();i--)
{
up[vec[t][i]]++;
if(dn[vec[t][i]]>=x&&up[vec[t][i]]>=x&&!hsh[vec[t][i]]) {hsh[vec[t][i]]=,add(vec[t][i],);}
}
}
return res;
}
int main()
{
n=read();int a,b;
for(int i=;i<=n;i++)
{
a=read(),b=read();
vec[a].push_back(b);
q[++cnt]=a;
}
sort(q+,q+cnt+);
cnt=unique(q+,q+cnt+)-q-;
for(int i=;i<=cnt;i++) sort(vec[q[i]].begin(),vec[q[i]].end());
int l=,r=n,ans=,res=;
while(l<=r)
{
int mid=l+r>>;
if(a=check(mid)) ans=mid,l=mid+,res=a;
else r=mid-;
}
printf("%d\n%d",ans,res);
}

luogu 3415 祭坛的更多相关文章

  1. luoguP3415 祭坛

    https://www.luogu.org/problemnew/show/P3415 考虑二分结界层数,将 n 个点按 x 大小依次加入答案,一行一行的做,用树状数组维护当前这一行中[0, x - ...

  2. Luogu P5603 小C与桌游【贪心+拓扑排序】

    [Description]https://www.luogu.com.cn/problem/P5603 \(\;\) 题意可以简化为:一个不保证联通,n个点,m条边的DAG(有向无环图),构造一个拓扑 ...

  3. Luogu 魔法学院杯-第二弹(萌新的第一法blog)

    虽然有点久远  还是放一下吧. 传送门:https://www.luogu.org/contest/show?tid=754 第一题  沉迷游戏,伤感情 #include <queue> ...

  4. luogu p1268 树的重量——构造,真正考验编程能力

    题目链接:http://www.luogu.org/problem/show?pid=1268#sub -------- 这道题费了我不少心思= =其实思路和标称毫无差别,但是由于不习惯ACM风格的题 ...

  5. HDU 4870 Rating(概率、期望、推公式) && ZOJ 3415 Zhou Yu

    其实zoj 3415不是应该叫Yu Zhou吗...碰到ZOJ 3415之后用了第二个参考网址的方法去求通项,然后这次碰到4870不会搞.参考了chanme的,然后重新把周瑜跟排名都反复推导(不是推倒 ...

  6. POJ 3415 后缀数组

    题目链接:http://poj.org/problem?id=3415 题意:给定2个串[A串和B串],求两个串公共子串长度大于等于k的个数. 思路:首先是两个字符串的问题.所以想用一个'#'把两个字 ...

  7. BZOJ2934 : [Poi1999]祭坛问题

    对于每个祭坛,算出每条线段阻碍它的角度区间,然后排序求并看看是否有空位即可,时间复杂度$O(n^2\log n)$. 这题在Main上官方时限是0.2S,因此需要几个常数优化: $1.$为了避免用at ...

  8. LA 3415 (二分图+最大独立集)

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...

  9. [luogu P2170] 选学霸(并查集+dp)

    题目传送门:https://www.luogu.org/problem/show?pid=2170 题目描述 老师想从N名学生中选M人当学霸,但有K对人实力相当,如果实力相当的人中,一部分被选上,另一 ...

随机推荐

  1. CAD绘制一个图象标记对象(com接口VB语言)

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...

  2. Android开发技巧一--weight属性实现视图的居中(半)显示

    面试时,一位面试官问到:“如果我想讲按钮居中显示,并且占据其父视图宽度的一半,应该怎么做到呢?”即实现这种效果: 我们使用weightSum属性和layout_weight属性实现这一要求: < ...

  3. Python学习笔记(3)动态类型

    is运算符 ==是值相等而is必须是相同的引用才可以 l=[1,2,3] m=[1,2,3] print(l==m) # True print(l is m) # False sys模块 getref ...

  4. Xcode 出现Thread 1: signal SIGABRT

    代码语言:C 出现原因:数组初始化时,循环赋值越界. 例 bool type [30]; for (int i = 0;i<100;i++) type = 0;

  5. 3. Python中的分支判断、循环

    本文利用的是Python 3.x版本,建议学习3.x版本 Python中的分支判断.循环 1. 分支条件判断 1.1 比较操作 以下是数之间常见的比较操作,例如5>3就是数学意义上的比较,5是大 ...

  6. [bzoj4567][Scoi2016][背单词] (贪心+trie树)

    Description Lweb 面对如山的英语单词,陷入了深深的沉思,“我怎么样才能快点学完,然后去玩三国杀呢?”.这时候睿智 的凤老师从远处飘来,他送给了 Lweb 一本计划册和一大缸泡椒,他的计 ...

  7. v-on(事件处理)

    1.监听事件  v-on:click="msg+=1" (msg是写在data里) 2.方法事件处理器 v-on:click = "jia" (jia是写在me ...

  8. Docker定制镜像

    定制镜像 除了使用定制好的镜像外,我们也可以通过定制实现符合自己环境的镜像. 在docker里面通过build方法来生成镜像,在生成镜像之前,我们需要一个Dockerfile脚本,脚本中包含的是一条一 ...

  9. 【Codeforces 924C】Riverside Curio

    [链接] 我是链接,点我呀:) [题意] 题意 [题解] 设第i天总共的线数为t[i] 水平线上线数为m[i]是固定的 水平线下的线数设为d[i] 则d[i]+m[i]+1=t[i] 也就是说问题可以 ...

  10. Leetcode 99.恢复二叉搜索树

    恢复二叉搜索树 二叉搜索树中的两个节点被错误地交换. 请在不改变其结构的情况下,恢复这棵树. 示例 1: 输入: [1,3,null,null,2] 输出: [3,1,null,null,2] 示例  ...