uoj #242【UR #16】破坏蛋糕
考虑把那最后一条直线拎出来,并且旋转到和\(y\)轴平行(其他直线同时一起旋转),然后它和其他直线相交形成\(n+1\)个区间,现在要知道这些区间是否处在一个面积有限的区域
可以发现一段在有限区域当且仅当区间的两侧区域都是有限的.所以对线的两侧分开考虑,先考虑左边,如果直线的一个区间旁边的区域有限,那么一定可以找到区间上面一条直线和下面一条直线在所求直线的左侧有交点,这要满足上面直线的斜率大于下面直线,并且他们能覆盖这两条直线与所求直线的交点形成的区间,使得一些连续段区间的左侧为有限区域,那么可以对其他直线从下往上加入,每加入一条直线就找到最下面的并且斜率小于他的直线,然后把对应交点形成的区间覆盖,这些直线可以单调栈维护,区间覆盖可以差分解决.右边同理,把大于小于反过来就行.最后看每一段是否在两边都被覆盖即可
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<cmath>
#include<ctime>
#include<queue>
#include<map>
#include<set>
#define LL long long
#define db double
using namespace std;
const int N=1e5+10;
const db pi=acos(-1),eps=1e-10;
int rd()
{
int x=0,w=1;char ch=0;
while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
struct point
{
db x,y;
point(){}
point(db nx,db ny){x=nx,y=ny;}
void rot(db cta)
{
db xx=x,yy=y;
x=cos(cta)*xx-sin(cta)*yy,y=cos(cta)*yy+sin(cta)*xx;
}
point operator - (const point &bb) const {return point(x-bb.x,y-bb.y);}
db operator * (const point &bb) const {return x*bb.y-y*bb.x;}
}a[N][2];
struct line
{
db k,b;
line(){}
line(point xx,point yy)
{
k=(xx.y-yy.y)/(xx.x-yy.x);
b=xx.y-k*xx.x;
}
bool operator < (const line &bb) const {return b<bb.b;}
}b[N];
int n,cf[N],c2[N],st[N],tp,an[N],ta;
int main()
{
n=rd();
for(int i=1;i<=n+1;++i)
{
int x=rd(),y=rd();
a[i][0]=point(x,y);
x=rd(),y=rd();
a[i][1]=point(x,y);
}
if(a[n+1][0].x>a[n+1][1].x) swap(a[n+1][0],a[n+1][1]);
point dtp(a[n+1][0].x,a[n+1][0].y);
for(int i=1;i<=n+1;++i)
a[i][0]=a[i][0]-dtp,a[i][1]=a[i][1]-dtp;
db cta=pi/2-atan2(a[n+1][1].y,a[n+1][1].x);
for(int i=1;i<=n+1;++i)
a[i][0].rot(cta),a[i][1].rot(cta);
for(int i=1;i<=n;++i)
b[i]=line(a[i][0],a[i][1]);
sort(b+1,b+n+1);
tp=0;
for(int i=1;i<=n;++i)
{
int l=1,r=tp,z=0;
while(l<=r)
{
int mid=(l+r)>>1;
if(b[st[mid]].k<b[i].k-eps) z=mid,r=mid-1;
else l=mid+1;
}
if(z) ++cf[st[z]],--cf[i];
if(!tp||b[st[tp]].k>b[i].k+eps) st[++tp]=i;
}
tp=0;
for(int i=1;i<=n;++i)
{
int l=1,r=tp,z=0;
while(l<=r)
{
int mid=(l+r)>>1;
if(b[st[mid]].k>b[i].k+eps) z=mid,r=mid-1;
else l=mid+1;
}
if(z) ++c2[st[z]],--c2[i];
if(!tp||b[st[tp]].k<b[i].k-eps) st[++tp]=i;
}
an[++ta]=0;
for(int i=1;i<n;++i)
{
cf[i]+=cf[i-1],c2[i]+=c2[i-1];
an[++ta]=cf[i]>0&&c2[i]>0;
}
an[++ta]=0;
for(int i=1;i<=ta;++i) printf("%d",an[i]);
return 0;
}
uoj #242【UR #16】破坏蛋糕的更多相关文章
- [UOJ UR#16]破坏发射台
来自FallDream的博客,未经允许,请勿转载,谢谢. 传送门 先考虑n是奇数的情况,很容易想到一个dp,f[i][0/1]表示转移到第i个数,第i个数是不是第一个数的方案数,然后用矩阵乘法优化一下 ...
- 【UOJ#242】【UR#16】破坏蛋糕(计算几何)
[UOJ#242][UR#16]破坏蛋糕(计算几何) 题面 UOJ 题解 为了方便,我们假定最后一条直线是从上往下穿过来的,比如说把它当成坐标系的\(y\)轴. 于是我们可以处理出所有交点,然后把它们 ...
- UOJ 241. 【UR #16】破坏发射台 [矩阵乘法]
UOJ 241. [UR #16]破坏发射台 题意:长度为 n 的环,每个点染色,有 m 种颜色,要求相邻相对不能同色,求方案数.(定义两个点相对为去掉这两个点后环能被分成相同大小的两段) 只想到一个 ...
- A. 【UR #16】破坏发射台
题解: 首先看n是偶数的 那么就是不需要满足对面这个性质的 这样就可以dp了 f[i][0/1]表示dp到第i位,当前数等于或不等于第一位的方案数 然后显然可以用矩阵优化 再考虑n为奇数 用一样的思路 ...
- UOJ 【UR #5】怎样跑得更快
[UOJ#62]怎样跑得更快 题面 这个题让人有高斯消元的冲动,但肯定是不行的. 这个题算是莫比乌斯反演的一个非常巧妙的应用(不看题解不会做). 套路1: 因为\(b(i)\)能表达成一系列\(x(i ...
- UOJ #22 UR #1 外星人
LINK:#22. UR #1 外星人 给出n个正整数数 一个初值x x要逐个对这些数字取模 问怎样排列使得最终结果最大 使结果最大的方案数又多少种? n<=1000,x<=5000. 考 ...
- UOJ.52.[UR #4]元旦激光炮(交互 思路)
题目链接 \(Description\) 交互库中有三个排好序的,长度分别为\(n_a,n_b,n_c\)的数组\(a,b,c\).你需要求出所有元素中第\(k\)小的数.你可以调用至多\(100\) ...
- UOJ【UR #12】实验室外的攻防战
题意: 给出一个排列$A$,问是否能够经过以下若干次变换变为排列$B$ 变换:若${A_i> A_i+1}$,可以${swap(A_i,A_i+1)}$ 考虑一个数字从A排列到B排列连出来的路径 ...
- 超实用的HTML代码段(赵荣娇)
第1章 创建HTML文档 11.1 HTML文档的基本结构 2 <html> <head> <title>Title of page</title> & ...
随机推荐
- RedisTemplate中zset类型的使用
简述 上一文中简述了使用StringRedisTemplate操作redis中的set类型,今天来记录一下操作zset类型的主要方法 代码 @RunWith(SpringRunner.class) @ ...
- Java实现QQ微信轰炸机1.2(斗图乞丐版)
之前有小可爱评论可以实现斗图的功能,原理上是行的通的,所以我就稍微改了一下,能够实现单个图片循环轰炸,如果大家感兴趣也可以自己探究实现多张图片循环轰炸,不废话了,直接上源码package QQWcha ...
- C++入门经典-例6.6-字符串复制
1:字符串复制函数strcpy的格式如下: strcpy(字符数组名,字符串) 其作用是把字符串中的字符串复制到字符数组中.需要注意的是,字符串结束标志'\0'也一同被复制. 注意是将后面的内容复制给 ...
- 20175215 2018-2019-2 第七周java课程学习总结
第八章 常用实用类 8.1 String类 Java专门提供了用来处理字符序列的String类.String类在java.lang包中,由于java.lang包中的类被默认引入,因此程序可以直接使用S ...
- 字符串 kotlin(6)
字符串用 String 类型表示.字符串是不可变的. 字符串的元素——字符可以使用索引运算符访问: s[i] . 可以用 for 循环迭代字符串: for (c in str) { println(c ...
- 常用IDE 教程(IntelliJ IDEA、Android Studio、Chrome)
1.IntelliJ IDEA 使用教程 http://wiki.jikexueyuan.com/project/intellij-idea-tutorial/ 2.Chrome 开发工具指南 htt ...
- 详解git pull和git fetch的区别
前言 在我们使用git的时候用的更新代码是git fetch,git pull这两条指令.但是有没有小伙伴去思考过这两者的区别呢?有经验的人总是说最好用git fetch+git merge,不建议用 ...
- git pull 覆盖本地代码
在使用Git的过程中,有些时候我们只想要git服务器中的最新版本的项目,对于本地的项目中修改不做任何理会,就需要用到Git pull的强制覆盖,具体代码如下: $ git fetch --all $ ...
- cocos2dx基础篇(26) 单例模式
单例模式,说的通俗一点就是:创建某个类的全局唯一静态实例对象.也就是说从它创建开始,一直到整个游戏程序结束才会释放资源,期间一直保存的着数据. 单例类在大部分游戏中应该是必不可少的部分,如整个游戏音乐 ...
- mapreduce的shufflue过程
一.Map阶段: a. 文件切片之后,每一个切片对应一个MapTask b. 在MapTask中,默认按行读取,每读取一行,就调用一次map方法 c. map方法在执行的时候会将结果(这个结果中已经包 ...