洛谷P3122 [USACO15FEB]圈住牛Fencing the Herd(计算几何+CDQ分治)
题面
题解
题目转化一下就是所有点都在直线\(Ax+By-C=0\)的同一侧,也就可以看做所有点代入\(Ax+By-C\)之后的值符号相同,我们只要维护每一个点代入直线之后的最大值和最小值,看看每条直线的最大最小值符号是否相同就好了
以最大值为例,我们强制\(B\geq 0\),那么能令这条直线取到最大值的点一定在所有点的上凸壳上,我们把凸壳搞出来,然后把所有直线按斜率从小到大排序,一遍扫过去就可以更新答案了
然而对于每条直线把前面所有点做个凸包?那有个吉儿用我还不如暴力枚举来得快
我们考虑\(CDQ\)分治,每次把\([l,mid]\)之间的点做一个凸包,然后用来更新\([mid+1,r]\)之间的答案就行了
//minamoto
#include<bits/stdc++.h>
#define R register
#define ll long long
#define inf 1e18
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
ll read(){
R ll res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
const int N=2e5+5;
struct node{
int x,y;
node(){}
node(R int xx,R int yy):x(xx),y(yy){}
inline node operator -(const node &b)const{return node(x-b.x,y-b.y);}
inline ll operator *(const node &b)const{return 1ll*x*b.y-1ll*y*b.x;}
inline bool operator <(const node &b)const{return x==b.x?y<b.y:x<b.x;}
}p[N],st[N];
struct query{
ll a,b,c;node p;int id;
query(){}
query(R ll a,R ll b,R ll c,R node P,R int Id):a(a),b(b),c(c),p(P),id(Id){}
}c[N],las[N];
struct qwq{ll a,b,c;int op,id;}q[N];
inline bool cmp1(const query &x,const query &y){return x.p*y.p>=0;}
inline bool cmp2(const query &x,const query &y){return x.p*y.p<=0;}
int ans[N];ll mn[N],mx[N],vc[N],maxn,minn;int op[N],n,m,tot,top,cnt,t;
inline void upd(R int id,R int x,R int y){
// printf("%d %d %d\n",id,x,y);
R ll val=las[id].a*x+las[id].b*y-las[id].c;
cmax(mx[id],val),cmin(mn[id],val);
}
void solve(int l,int r){
if(l==r)return;
int mid=(l+r)>>1;
solve(l,mid),solve(mid+1,r),top=cnt=tot=0;
fp(i,l,mid)if(q[i].op&1)p[++tot]=node(q[i].a,q[i].b);
fp(i,mid+1,r)if(q[i].op&2)c[++cnt]=query(q[i].a,q[i].b,q[i].c,node(q[i].b,-q[i].a),q[i].id);
if(!tot||!cnt)return;
sort(p+1,p+1+tot),st[top=1]=p[1];
fp(i,2,tot){
while(top>1&&(p[i]-st[top-1])*(st[top]-st[top-1])>=0)--top;
st[++top]=p[i];
}
sort(c+1,c+1+cnt,cmp1);
// printf("%d %d %d\n",l,r,cnt);
// fp(i,1,cnt)printf("%d\n",c[i].id);
for(R int i=1,j=1;i<=top;++i){
while(j<=cnt&&(i+1>top||(c[j].p*(st[i+1]-st[i]))>=0))
upd(c[j].id,st[i].x,st[i].y),++j;
}
st[top=1]=p[1];
fp(i,2,tot){
while(top>1&&(p[i]-st[top-1])*(st[top]-st[top-1])<=0)--top;
st[++top]=p[i];
}
sort(c+1,c+1+cnt,cmp2);
for(R int i=1,j=1;i<=top;++i){
while(j<=cnt&&(i+1>top||c[j].p*(st[i+1]-st[i])<=0))
upd(c[j].id,st[i].x,st[i].y),++j;
}
}
int main(){
// freopen("testdata.in","r",stdin);
n=read(),m=read(),maxn=-inf,minn=inf;
fp(i,1,n)q[i].op=1,q[i].a=read(),q[i].b=read(),cmax(maxn,q[i].a),cmin(minn,q[i].a);
t=n;
fp(i,1,m)ans[i]=-1;
fp(i,1,m){
++t,op[i]=q[t].op=read();
if(q[t].op&1)q[t].a=read(),q[t].b=read(),cmax(maxn,q[t].a),cmin(minn,q[t].a);
else{
q[t].a=read(),q[t].b=read(),q[t].c=read();
if(!q[t].b)ans[i]=(-1.0*q[t].c/q[t].a<minn||-1.0*q[t].c/q[t].a>maxn),--t;
else{
if(q[t].b<0)q[t].a=-q[t].a,q[t].b=-q[t].b,q[t].c=-q[t].c;
mn[i]=inf,mx[i]=-inf,q[t].id=i;
las[i].a=q[t].a,las[i].b=q[t].b,las[i].c=q[t].c;
}
}
}
// fp(i,1,t)printf("%d %d %lld %lld %lld\n",q[i].op,q[i].id,q[i].a,q[i].b,q[i].c);
solve(1,t);
fp(i,1,t)if(q[i].op&2)ans[q[i].id]=(mx[q[i].id]<0||mn[q[i].id]>0);
fp(i,1,m)if(op[i]&2)puts(ans[i]?"YES":"NO");
return 0;
}
洛谷P3122 [USACO15FEB]圈住牛Fencing the Herd(计算几何+CDQ分治)的更多相关文章
- 洛谷 P3810 【模板】三维偏序(陌上花开) (cdq分治模板)
在solve(L,R)中,需要先分治solve两个子区间,再计算左边区间修改对右边区间询问的贡献. 注意,计算额外的贡献时,两子区间各自内部的顺序变得不再重要(不管怎么样左边区间的都发生在右边之前), ...
- 洛谷P3374 【模板】树状数组 1(CDQ分治)
题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. ...
- 洛谷4951 地震 bzoj1816扑克牌 洛谷3199最小圈 / 01分数规划
洛谷4951 地震 #include<iostream> #include<cstdio> #include<algorithm> #define go(i,a,b ...
- HAOI2006 (洛谷P2341)受欢迎的牛 题解
HAOI2006 (洛谷P2341)受欢迎的牛 题解 题目描述 友情链接原题 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就是一头明星奶牛.所有奶 牛都是自恋狂,每头奶牛总是喜欢自己的.奶牛之 ...
- Bzoj1486/洛谷P3199 最小圈(0/1分数规划+spfa)/(动态规划+结论)
题面 Bzoj 洛谷 题解(0/1分数规划+spfa) 考虑\(0/1\)分数规划,设当前枚举到的答案为\(ans\) 则我们要使(其中\(\forall b_i=1\)) \[ \frac{\sum ...
- 洛谷P3085 [USACO13OPEN]阴和阳Yin and Yang(点分治,树上差分)
洛谷题目传送门 闲话 偶然翻到一道没有题解的淀粉质,想证明一下自己是真的弱 然而ZSYC(字符串组合)早就切了 然后证明成功了,WA到怀疑人生,只好借着ZSY的代码拍,拍了几万组就出来了... 思路 ...
- 洛谷 P3120 [USACO15FEB]牛跳房子(金)Cow Hopscotch (Gold)
P3120 [USACO15FEB]牛跳房子(金)Cow Hopscotch (Gold) 就像人类喜欢跳格子游戏一样,FJ的奶牛们发明了一种新的跳格子游戏.虽然这种接近一吨的笨拙的动物玩跳格子游戏几 ...
- 洛谷P3120 [USACO15FEB]牛跳房子(动态开节点线段树)
题意 题目链接 Sol \(f[i][j]\)表示前\(i\)行\(j\)列的贡献,转移的时候枚举从哪里转移而来,复杂度\(O(n^4)\) 然后考虑每一行的贡献,动态开节点线段树维护一下每种颜色的答 ...
- 洛谷P2341受欢迎的牛
传送门啦 这是一个tarjan强连通分量与出度结合的例题. 先明确一下题意,如果这个点(缩点之后的)没有出度,这个点才能成为明星牛(明星牛的定义是:所有牛都喜欢他才可以). 由于我们进行了缩点,所以我 ...
随机推荐
- Lambda中的常用sql方法
1.Groupby 对集合进行分组,如: var dllList = _menuMan.Load(c => c.TXT_ASSEMBLYNAME != null).GroupBy(c=>c ...
- 不需要SDK调用图灵机器人的方法
图灵机器人的调用其实就是你给服务器发一个文字消息过去,他回你一个,看起来模仿人类对话一样. 不知道为什么要弄个SDK这么麻烦的方法,以前的接口官网上已经没有了,但是还是可以用的.返回的是JSON但也懒 ...
- DDD学习笔录——提炼问题域之有效提炼知识的模型(三)
方式六:延迟对模型中概念的命名 对领域建模时命名很重要. 因为在不断的知识提炼过程中经常会发现已经被命名的概念与你最初理解的有出入,这时你当初的命名就会变成一个问题.其问题在于 最初选作名称的这个词 ...
- BurpSuite—-Spider模块(蜘蛛爬行)
一.简介 Burp Spider 是一个映射 web 应用程序的工具.它使用多种智能技术对一个应用程序的内容和功能进行全面的清查. Burp Spider 通过跟踪 HTML 和 JavaScript ...
- PHP下生成非重复的id
PHP在多进程运行的情况下,如果不采用内存锁或者文件锁,基本没办法能解决生成唯一Id的问题.试过了静态变量.单例模式等等.查询到php里的uniqid()函数,最后还是找到了一个折中方式,虽然还是有可 ...
- 【原】Coursera—Andrew Ng机器学习—课程笔记 Lecture 5 Octave Tutorial—5.6 向量化 Vectorization
5.6 向量化 Vectorization 参考视频: 5 - 6 - Vectorization (14 min).mkv 下面是向量化的小例子,如果将所有u(j) .所有v(j).所有w(j)都看 ...
- 流Stream
System.IO 提供了一个抽象类Stream , Stream类 支持对字节的读写操作.所谓的“流”,指的是Stream,也就是所谓的一个文件区.这个文件区中存储着的信息可以是在内存中,也可以是在 ...
- 局部变量和static变量的区别
static int a ; int b; scanf_s("%d %d",&a,&b); 01374212 lea eax,[b] 01374215 push e ...
- 19、SOAP安装,运用与比对结果解释
转载:http://www.dengfeilong.com/post/Soap2.html https://blog.csdn.net/zhu_si_tao/article/details/71108 ...
- list 的扩展
数据挖掘中会遇到添加多个新的特征s,对一个feature = list()来说, 除了可以用 feature.append('xx') # 在尾部添加一个特征 feature.extend(['xx' ...