传送门

Description

有一天,小 A 的母亲对他家里的卫生状况非常不满意,他的房间里有非常多的苍蝇。在母亲的威逼利诱下,小 A 拿起了苍蝇拍去消灭家里的苍蝇。然而,小 A 以前从来没有亲手消灭过任何一只苍蝇,以至于在他拿起苍蝇拍的那一刻,他对苍蝇起了怜悯之心 —— 他不想伤害任何一只苍蝇。现在,小 A 面前的窗户上有 只苍蝇,他想知道有多少种方式可以在他拿起苍蝇拍拍窗户的时候,不伤害任何一只苍蝇。

窗户可以看作是一个左下角位于坐标系原点的矩形,苍蝇拍可以看作是一个多边形。在小 A 向窗户挥苍蝇拍时,对应多边形的顶点必须位于坐标系的整点上,并且苍蝇拍所在位置不能超过窗户所在范围。一只苍蝇会被伤害当且仅当小 A 用苍蝇拍拍向窗户时,苍蝇位于苍蝇拍内部、边上或顶点上。

Solution

和这场比赛的T3是类似的sailing

同样是处理出01序列,将其中一个反转用FFT卷积优化

难度在于如何求出那些在多边形中的点

显然一个一个点求太慢了

所以考虑一列一列的求,事先先处理出与这一列相交的交点

第\(2n-1\)到\(2n\)个交点内的点都是处于多边形的

人形大常数,跑得还不如bitset快

Code 

#include<bits/stdc++.h>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define ll long long
#define db double
#define reg register
#define ri reg int i
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
const int NN=1<<19|5;
const int MS=2.6e4,MN=505,inf=0x3f3f3f3f;
const db eps=1e-12,Pi=std::acos(-1.);
struct Node{int x,y;}S[MS],T[MS];
int Xp,Yp,N,K,ans;
db P[MS];
bool _S[MN][MN],_T[MN][MN];
struct complex
{
double x,y;
complex(double x=0,double y=0):x(x),y(y){}
inline complex operator+(const complex& o)const{return complex(x+o.x,y+o.y);}
inline complex operator-(const complex& o)const{return complex(x-o.x,y-o.y);}
inline complex operator*(const complex& o)const{return complex(x*o.x-y*o.y,x*o.y+y*o.x);}
inline void swap(complex& o){register complex t=o;o=(*this);*this=t;}
}a[NN],b[NN];
int Nn,di,pos[NN];
inline void FFT(complex *a,int type)
{
register int i,j,p,k;
for(i=0;i<Nn;++i)if(i<pos[i])a[i].swap(a[pos[i]]);
for(i=1;i<Nn;i<<=1)
{
complex wn(cos(Pi/i),type*sin(Pi/i));
for(p=i<<1,j=0;j<Nn;j+=p)
{
complex w(1,0);
for(k=0;k<i;++k,w=w*wn)
{
complex X=a[j+k],Y=w*a[j+i+k];
a[j+k]=X+Y;a[j+i+k]=X-Y;
}
}
}
}
inline void combine(complex *a,complex *b,int n,int m)
{
for(Nn=1;Nn<=n+m;Nn<<=1,di++);
for(ri=0;i<Nn;++i) pos[i]=(pos[i>>1]>>1)|((i&1)<<(di-1));
FFT(a,1);FFT(b,1);for(ri=0;i<Nn;++i)a[i]=a[i]*b[i];FFT(a,-1);
}
int main()
{
#ifdef PAC
freopen("fly4.in","r",stdin);
freopen("fly4.out","w",stdout);
#endif
int xi=inf,yi=inf,xx=-inf,yx=-inf,lenx,leny,tt;
reg int i,j,x,y;
Xp=read();Yp=read();N=read();
for(i=1;i<=N;++i) _S[S[i].x=read()][S[i].y=read()]=1;
K=read();
for(i=1;i<=K;++i)
{
T[i].x=read();T[i].y=read();
xi=min(xi,T[i].x);xx=max(xx,T[i].x);
yi=min(yi,T[i].y);yx=max(yx,T[i].y);
}
lenx=xx-xi;leny=yx-yi;
if(lenx>Xp||leny>Yp) return 0*puts("0");
for(i=1;i<=K;++i) _T[T[i].x-=xi][T[i].y-=yi]=1;
for(x=0;x<=lenx;++x)
{
tt=0;memset(P,0,sizeof P);P[0]=-inf;
for(i=1;i<=K;++i)
{
Node a=T[i],b=T[i%K+1];if(a.y>b.y) std::swap(a,b);
if(a.x==x&&b.x==x)for(y=a.y;y<=b.y;++y) _T[x][y]=1;
else if((a.x-x)*(b.x-x)<=0&&!(a.x==x&&b.x>x)&&!(b.x==x&&a.x>x))
P[++tt]=(db)(x-a.x)*(db)(a.y-b.y)/(db)(a.x-b.x)+(db)a.y;
}
std::sort(P+1,P+tt+1);
for(i=0,y=0;y<=leny;_T[x][y]|=((i^((~i&1)&&y-P[i]<eps))&1),++y)while(i+1<=tt&&(db)y>=P[i+1])++i;
}
for(i=0;i<=Xp;++i)for(j=0;j<=Yp;++j)a[i*(Yp+1)+j].x=_S[i][j]?1.:0.;
int LEN1=(Xp+1)*(Yp+1),LEN2=0; for(i=0;i<=lenx;++i)
{
for(j=0;j<=leny;++j)b[LEN2++].x=_T[i][j]?1.:0.;
if(i!=lenx) for(j=leny+1;j<=Yp;++j) b[LEN2++].x=0.;
}
std::reverse(b,b+LEN2);
combine(a,b,LEN1,LEN2);
for(i=0;i<=Xp-lenx;++i)for(j=0;j<=Yp-leny;++j)
if(((int)(a[LEN2+(i*(Yp+1)+j)-1].x/Nn+.5))==0) ++ans;
printf("%d\n",ans);
return 0;
}

Blog来自PaperCloud,未经允许,请勿转载,TKS!

「雅礼集训 2017 Day10」拍苍蝇的更多相关文章

  1. LOJ#6049. 「雅礼集训 2017 Day10」拍苍蝇(计算几何+bitset)

    题面 传送门 题解 首先可以用一个矩形去套这个多边形,那么我们只要枚举这个矩形的左下角就可以枚举完所有多边形的位置了 我们先对每一个\(x\)坐标开一个\(bitset\),表示这个\(x\)坐标里哪 ...

  2. LOJ#6047. 「雅礼集训 2017 Day10」决斗(set)

    题面 传送门 题解 这么简单一道题我考试的时候居然只打了\(40\)分暴力? 如果我们把每个点的\(a_i\)记为\(deg_i-1\),其中\(deg_i\)表示有\(deg_i\)个数的\(A_i ...

  3. LOJ#6048. 「雅礼集训 2017 Day10」数列(线段树)

    题面 传送门 题解 我的做法似乎非常复杂啊-- 首先最长上升子序列长度就等于把它反过来再接到前面求一遍,比方说把\(2134\)变成\(43122134\),实际上变化之后的求一个最长上升子序列和方案 ...

  4. LOJ_6045_「雅礼集训 2017 Day8」价 _最小割

    LOJ_6045_「雅礼集训 2017 Day8」价 _最小割 描述: 有$n$种减肥药,$n$种药材,每种减肥药有一些对应的药材和一个收益. 假设选择吃下$K$种减肥药,那么需要这$K$种减肥药包含 ...

  5. 「雅礼集训 2017 Day7」事情的相似度

    「雅礼集训 2017 Day7」事情的相似度 题目链接 我们先将字符串建后缀自动机.然后对于两个前缀\([1,i]\),\([1,j]\),他们的最长公共后缀长度就是他们在\(fail\)树上对应节点 ...

  6. 「雅礼集训 2017 Day2」解题报告

    「雅礼集训 2017 Day2」水箱 我怎么知道这种题目都能构造树形结构. 根据高度构造一棵树,在树上倍增找到最大的小于约束条件高度的隔板,开一个 \(vector\) 记录一下,然后对于每个 \(v ...

  7. 「雅礼集训 2017 Day1」 解题报告

    「雅礼集训 2017 Day1」市场 挺神仙的一题.涉及区间加.区间除.区间最小值和区间和.虽然标算就是暴力,但是复杂度是有保证的. 我们知道如果线段树上的一个结点,\(max=min\) 或者 \( ...

  8. [LOJ 6031]「雅礼集训 2017 Day1」字符串

    [LOJ 6031] 「雅礼集训 2017 Day1」字符串 题意 给定一个长度为 \(n\) 的字符串 \(s\), \(m\) 对 \((l_i,r_i)\), 回答 \(q\) 个询问. 每个询 ...

  9. [LOJ 6030]「雅礼集训 2017 Day1」矩阵

    [LOJ 6030] 「雅礼集训 2017 Day1」矩阵 题意 给定一个 \(n\times n\) 的 01 矩阵, 每次操作可以将一行转置后赋值给某一列, 问最少几次操作能让矩阵全为 1. 无解 ...

随机推荐

  1. C# vb .net实现高斯模糊

    在.net中,如何简单快捷地实现Photoshop滤镜组中的高斯模糊效果呢?答案是调用SharpImage!专业图像特效滤镜和合成类库.下面开始演示关键代码,您也可以在文末下载全部源码: 设置授权 第 ...

  2. Java文件字符流

    1.字符编码(Character encoding)和编码集(Character set) 字符编码(Character encoding)是将字符转为字节或字节数组的过程. 字符集(Characte ...

  3. 【洛谷 P4070】 [SDOI2016]生成魔咒(后缀自动机)

    题目链接 建出\(SAM\)后,不同子串个数就是\(\sum len(i)-len(fa(i))\) 因为\(SAM\)在线的,所以每加入一个字符就能直接加上其贡献,于是这道题就没了. 因为\(x\) ...

  4. OO第三单元(地铁,JML)单元总结

    OO第三单元(地铁,JML)单元总结 这是我们OO课程的第二个单元,这个单元的主要目的是让我们熟悉并了解JML来是我们具有规格化编程架构的思想.这个单元的主题一开始并不明了,从第一次作业的路径到第二次 ...

  5. JavaScript的变量和常量

    1.什么是常量? 常量表示一些固定不变的数据 现实生活中人的性别其实就可以看做是常量, 生下来是男孩一辈子都是男孩, 生下来是女孩一辈子都是女孩 2.JavaScript中常量的分类 2.1整型常量 ...

  6. xcode 手动管理内存 的相关知识点总结

    一.XCode4.2以后支持自动释放内存ARC xcode自4.2以后就支持自动释放内存了,但有时我们还是想手动管理内存,这如何处理呢. 很简单,想要取消自动释放,只要在  Build Setting ...

  7. Django:Python3.6.2+Django2.0配置MySQL 转载

    Django默认使用的数据库是python自带的SQLlite3,但SQLlite并不适用于大型的项目,因此我将数据库换成了MySQL,下面介绍下Django如何配置数据库... 我使用的版本是:Py ...

  8. Django异常 - ImportError: No module named django.core.management

    Django错误 - ImportError: No module named django.core.management问题描述:在命令行输入 manage.py runserver,提示找不到d ...

  9. 【Flask】 python学习第一章 - 3.0 正则转换和错误捕捉

    3.1正则转换器定义 Class RegexConverter(BaseConverter): regex = "[0-9]{6}" app.url_map.converters[ ...

  10. node绑定域名 nginx篇

    创建nodejs文件,并测试执行有没有问题. var express = require('express'); var app = express(); app.get('/', function ...