「JSOI2018」战争

解题思路

我们需要每次求给一个凸包加上一个向量后是否与另外一个凸包相交,也就是说是否存在

\[b\in B,(b+w)\in A
\]

这里 \(A, B\) 表示凸包内部的点集,可以转化一步变成

\[a\in A,b \in B,b+w=a \\ w =a -b
\]

那相当于对 \(A,(-B)\) 作闵可夫斯基和,判断 \(w\) 是否在新的凸包内部,把新的凸包划分成三角区域,让 \(w\) 和原点做一条向量,二分一下在哪个区域然后判断一下在区域内部还是外部就可以了,复杂度 \(\mathcal O(n \log n)\) 。

code

/*program by mangoyang*/
#include<bits/stdc++.h>
#define inf (0x7f7f7f7f)
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
int ch = 0, f = 0; x = 0;
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
if(f) x = -x;
}
const int N = 1000005;
struct P{
ll x, y;
friend P operator + (P a, P b){ return (P){a.x + b.x, a.y + b.y}; }
friend P operator - (P a, P b){ return (P){a.x - b.x, a.y - b.y}; }
friend ll operator * (P a, P b){ return a.x * b.y - b.x * a.y; }
inline ll dis(){ return x * x + y * y; }
}A[N], B[N], C[N], s1[N], s2[N], st[N], O;
int n, m, q;
inline bool cmp1 (P A, P B){
return A.y != B.y ? A.y < B.y : A.x < B.x;
}
inline bool cmp2 (P A, P B){
//叉积一样按照离原点距离排,防止较远的点被近的点日掉
ll res = (A - O) * (B - O);
return res ? res > 0 : (A - O).dis() < (B - O).dis();
}
inline int convex(P *A, int len){
//求点集 A 的凸包并返回凸包大小
sort(A + 1, A + len + 1, cmp1); O = A[1];
sort(A + 2, A + len + 1, cmp2);
int top = 1; st[top] = A[1];
for(int i = 2; i <= len; i++){
while(top > 1 && (st[top] - st[top-1]) * (A[i] - st[top-1]) <= 0) top--;
st[++top] = A[i];
}
for(int i = 1; i <= top; i++) A[i] = st[i];
return top;
}
inline int inconvex(P x, P *A, int len){
//判断点 x 是否在大小为len的凸包 A 里,二分找到向量所在的三角区域
O = A[1];
if((x - O) * (A[2] - O) > 0 || (x - O) * (A[len] - O) < 0) return 0;
int pos = lower_bound(A + 2, A + len + 1, x, cmp2) - A - 1;
return (x - A[pos]) * (A[pos%len+1] - A[pos]) <= 0; }
inline int Minkowski(P *A, P *B, P *C, int n, int m){
//将大小为 n, m 的凸包 A, B 的闵可夫斯基和存在 C 中,并返回凸包大小
int tot1 = 0, tot2 = 0;
for(int i = 1; i < n; i++) s1[++tot1] = A[i+1] - A[i];
s1[++tot1] = A[1] - A[n];
for(int i = 1; i < m; i++) s2[++tot2] = B[i+1] - B[i];
s2[++tot2] = B[1] - B[m];
int p1 = 1, p2 = 1, tot = 1; C[tot] = A[1] + B[1];
for(; p1 <= n && p2 <= m; tot++)
C[tot+1] = C[tot] + (s1[p1] * s2[p2] >= 0 ? s1[p1++] : s2[p2++]);
for(; p1 <= n; p1++, tot++) C[tot+1] = C[tot] + s1[p1];
for(; p2 <= m; p2++, tot++) C[tot+1] = C[tot] + s2[p2];
return tot = convex(C, tot);
}
int main(){
read(n), read(m), read(q);
for(int i = 1; i <= n; i++) read(A[i].x), read(A[i].y);
n = convex(A, n);
for(int i = 1; i <= m; i++)
read(B[i].x), read(B[i].y), B[i].x = -B[i].x, B[i].y = -B[i].y;
m = convex(B, m);
int len = Minkowski(A, B, C, n, m);
while(q--){
ll x, y; read(x), read(y);
printf("%d\n", inconvex((P){x, y}, C, len));
}
return 0;
}

「JSOI2018」战争的更多相关文章

  1. 【LOJ】#2549. 「JSOI2018」战争

    题解 仔细分析了一下,如果写个凸包+每次暴力半平面交可以得到70分,正解有点懵啊 然后用到了一个非常结论,但是大概出题人觉得江苏神仙一个个都可以手证的结论吧.. Minkowski sum 两个凸包分 ...

  2. 「JLOI2015」战争调度 解题报告

    「JLOI2015」战争调度 感觉一到晚上大脑就宕机了... 题目本身不难,就算没接触过想想也是可以想到的 这个满二叉树的深度很浅啊,每个点只会和它的\(n-1\)个祖先匹配啊 于是可以暴力枚举祖先链 ...

  3. 「JLOI2015」战争调度

    题目 [内存限制:256 MiB][时间限制:1000 ms] [标准输入输出][题目类型:传统][评测方式:文本比较] 题目描述 脸哥最近来到了一个神奇的王国,王国里的公民每个公民有两个下属或者没有 ...

  4. LOJ 2550 「JSOI2018」机器人——找规律+DP

    题目:https://loj.ac/problem/2550 只会写20分的搜索…… #include<cstdio> #include<cstring> #include&l ...

  5. LOJ 2548 「JSOI2018」绝地反击 ——二分图匹配+网络流手动退流

    题目:https://loj.ac/problem/2548 如果知道正多边形的顶点,就是二分答案.二分图匹配.于是写了个暴力枚举多边形顶点的,还很愚蠢地把第一个顶点枚举到 2*pi ,其实只要 \( ...

  6. LOJ 2551 「JSOI2018」列队——主席树+二分

    题目:https://loj.ac/problem/2551 答案是排序后依次走到 K ~ K+r-l . 想维护一个区间排序后的结果,使得可以在上面二分.求和:二分可以知道贡献是正还是负. 于是想用 ...

  7. LOJ 2547 「JSOI2018」防御网络——思路+环DP

    题目:https://loj.ac/problem/2547 一条树边 cr->v 会被计算 ( n-siz[v] ) * siz[v] 次.一条环边会被计算几次呢?于是去写了斯坦纳树. #in ...

  8. LOJ #2547 Luogu P4517「JSOI2018」防御网络

    好像也没那么难写 LOJ #2547 Luogu P4517 题意 在一棵点仙人掌中等概率选择一个点集 求选出点集的斯坦纳树大小的期望 定义点仙人掌为不存在一个点在多个简单环中的连通图 斯坦纳树为在原 ...

  9. LOJ 2546 「JSOI2018」潜入行动——树形DP

    题目:https://loj.ac/problem/2546 dp[ i ][ j ][ 0/1 ][ 0/1 ] 表示 i 子树,用 j 个点,是否用 i , i 是否被覆盖. 注意 s1<= ...

随机推荐

  1. Python练习-time模块

    明天的明天的明天,雾草! # 编辑者:闫龙 #显示当前时间三天后是星期几? import time t = time.time()+((24*3600)*3) tl = time.localtime( ...

  2. mybatis的配置文件中<selectKey>标签问题

    1.mybatis的配置文件中,使用sequence生成主键 未执行add方法之前,主键未生成(null):刚执行add之后,主键即生成(212) 这里的重点是,一旦执行add方法,配置文件中的sel ...

  3. jQuery入门——(二)

    0.基本知识 $与jQuery等价,$.fun代表jQuery的全局方法. jQuery必须首先导入JQuery库, jQuery的事件都不带on,例如 $("#btn").cli ...

  4. java连接redis无法连接,报异常RedisConnectionException

    不管是spring还是原生jedis连接redis,如果连不上多半是linux服务器的问题: 1 首先确保redis端口开放: 把6379或者redis的端口开放即可 2 redis.conf配置注释 ...

  5. flask基础之app初始化(四)

    前言 flask的核心对象是Flask,它定义了flask框架对于http请求的整个处理逻辑.随着服务器被启动,app被创建并初始化,那么具体的过程是这样的呢? 系列文章 flask基础之安装和使用入 ...

  6. 读书笔记 effective c++ Item 28 不要返回指向对象内部数据(internals)的句柄(handles)

    假设你正在操作一个Rectangle类.每个矩形可以通过左上角的点和右下角的点来表示.为了保证一个Rectangle对象尽可能小,你可能决定不把定义矩形范围的点存储在Rectangle类中,而是把它放 ...

  7. python基础--类的方法

    一:类的方法说明 类的方法分为实例方法,析构方法,构造方法,类方法,静态方法,属性方法,等等 类方法和静态方法都可以被类和类实例调用,类实例方法仅可以被类实例调用 类方法的隐含调用参数是类,而类实例方 ...

  8. mac下---charles抓包https

    网上找的很多安装包都有问题,终于找到个可用的! 下载地址:  http://pan.baidu.com/s/1pLAONbX ———————————————————————————— 教程转载:htt ...

  9. java 多线程总结篇2之——Thread类及常用函数

    此片文章主要总结的是Thread类及相关的基础概念和API,首先需要厘清线程调度中的几个基本概念: 一.线程调度的基本方法 1.调整线程优先级:Java线程有优先级,优先级高的线程会获得较多的运行机会 ...

  10. springMVC源码分析--HttpMessageConverter数据转化(一)

    之前的博客我们已经介绍了很多springMVC相关的模块,接下来我们介绍一下springMVC在获取参数和返回结果值方面的处理.虽然在之前的博客老田已经分别介绍了参数处理器和返回值处理器: (1)sp ...