题意

题解

神仙结论题。

结论: 一个点集合法当且仅当其凸包上的两种颜色点分别连续。

证明:

必要性显然。

充分性: 考虑对于一个不同色三角形\(ABC\),不妨设点\(A\)为白点,点\(B,C\)为黑点。若形内无白点,则随便连,显然成立。若形内有白点,则任取一白点\(S\), 对三角形\(SBC,BAS,CAS\)内部的点分别连边(递归构造),最后连接\(SA\).

再考虑一个凸包,设在逆时针方向上最后一个白点是\(U\), 最后一个黑点是\(V\), 则连接\(UV\), 把凸包剖成两个部分,一部分只有\(V\)是黑,一部分只有\(U\)是白。然后进行如图所示三角剖分,每个三角形内连上即可。

知道了结论,这题就很简单了。

勿忘非空。

代码

#include<bits/stdc++.h>
#define llong long long
using namespace std; const int N = 1e5;
const int P = 1e9+7;
struct Point
{
llong x,y; int c,id;
Point() {}
Point(int _x,int _y) {x = _x,y = _y;}
} a[N+3],ch[N+3];
bool f[N+3];
Point operator -(Point x,Point y) {return Point(x.x-y.x,x.y-y.y);}
llong Cross(Point x,Point y) {return x.x*y.y-x.y*y.x;}
int n,sz; bool cmp_ang(Point x,Point y) {return Cross(x-a[1],y-a[1])>0;} int main()
{
scanf("%d",&n);
for(int i=1; i<=n; i++) scanf("%lld%lld%d",&a[i].x,&a[i].y,&a[i].c);
for(int i=2; i<=n; i++) {if(a[i].x<a[1].x||(a[i].x==a[1].x&&a[i].y<a[1].y)) {swap(a[i],a[1]);}}
sort(a+2,a+n+1,cmp_ang);
for(int i=1; i<=n; i++) a[i].id = i;
sz = 1; ch[1] = a[1];
for(int i=2; i<=n; i++)
{
while(sz>=2 && Cross(ch[sz]-ch[sz-1],a[i]-ch[sz-1])<0) {sz--;}
sz++; ch[sz] = a[i];
}
// printf("ch: "); for(int i=1; i<=sz; i++) printf("(%lld,%lld) ",ch[i].x,ch[i].y); puts("");
int mx1 = 0,mn1 = n,mx2 = 0,mn2 = n; llong ans;
for(int i=1; i<=sz; i++)
{
if(ch[i].c==1) {mx1 = max(mx1,i),mn1 = min(mn1,i);}
else if(ch[i].c==2) {mx2 = max(mx2,i),mn2 = min(mn2,i);}
}
// printf("sz=%d mn1=%d mx1=%d mn2=%d mx2=%d\n",sz,mn1,mx1,mn2,mx2);
if(mx1<mn1 && mx2<mn2)
{
ans = (1ll*sz*sz-sz+2ll)%P;
}
else if(mx1<mn1) //only 2
{
ans = 1ll;
for(int i=mn2+1,j=0; i<=mn2+sz; i++)
{
int ii = i>sz?i-sz:i;
if(ch[ii].c==0) {j++;}
else {ans += 1ll*j*(j+1ll)/2ll; j = 0;}
}
ans %= P;
}
else if(mx2<mn2) //only 1
{
ans = 1ll;
for(int i=mn1+1,j=0; i<=mn1+sz; i++)
{
int ii = i>sz?i-sz:i;
if(ch[ii].c==0) {j++;}
else {ans += 1ll*j*(j+1ll)/2ll; j = 0;}
}
ans %= P;
}
else
{
if(mn1>mn2)
{
for(int i=mn1; i<=mx1; i++)
{
if(ch[i].c==2) {puts("0"); return 0;}
}
int l = -1,r = -1;
for(int i=mx1; ch[i].c!=2; i=(i==sz?1:i+1))
{
l++;
}
for(int i=mn1; ch[i].c!=2; i=(i==1?sz:i-1))
{
r++;
}
ans = 1ll*(l+1ll)*(r+1ll)%P;
}
else
{
for(int i=mn2; i<=mx2; i++)
{
if(ch[i].c==1) {puts("0"); return 0;}
}
int l = -1,r = -1;
for(int i=mx2; ch[i].c!=1; i=(i==sz?1:i+1))
{
l++;
}
for(int i=mn2; ch[i].c!=1; i=(i==1?sz:i-1))
{
r++;
}
ans = 1ll*(l+1ll)*(r+1ll)%P;
}
}
for(int i=1; i<=sz; i++)
{
f[ch[i].id] = true;
}
int cnt1 = 0,cnt2 = 0;
for(int i=1; i<=n; i++)
{
if(f[i]==false && a[i].c==0) {ans=(ans<<1)%P;}
if(a[i].c==1) cnt1++;
if(a[i].c==2) cnt2++;
}
if(cnt1==0) {ans--;} if(cnt2==0) {ans--;}
ans = (ans+P)%P;
printf("%lld\n",ans);
return 0;
}

[JOI2012春季合宿]Constellation (凸包)的更多相关文章

  1. BZOJ 4388 [JOI2012春季合宿]Invitation (线段树、二叉堆、最小生成树)

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=4388 题解 模拟Prim算法? 原题所述的过程就是Prim算法求最大生成树的过程.于是我 ...

  2. BZOJ 4221 [JOI2012春季合宿]Kangaroo (DP)

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=4221 题解 orz WYC 爆切神仙DP 首先将所有袋鼠按大小排序.考虑从前往后DP, ...

  3. [JOI2012春季合宿]Rotate (链表)

    题意 题解 又是一道神仙题-- 显然的做法是大力splay,时间复杂度\(O((N+Q)N\log N)\), 可以卡掉. 正解: 使用十字链表维护矩阵,在周围增加第\(0\)行/列和第\((n+1) ...

  4. UOJ356 [JOI2017春季合宿] Port Facility 【启发式合并】【堆】【并查集】

    题目分析: 好像跑得很快,似乎我是第一个启发式合并的. 把玩具看成区间.首先很显然如果有两个玩具的进出时间有$l1<l2<r1<r2$的关系,那么这两个玩具一定在不同的栈中间. 现在 ...

  5. [JOI2017春季合宿]Port Facility[set、二分图]

    题意 你有两个栈,有 \(n\) 个货物,每个货物有一个进栈时间和出栈时间(所有时间的并集是1~2n),问有多少种不同的入栈方案. \(n\le 10^6\) 分析 把每个货物的存在看成区间,相交的区 ...

  6. UOJ #356. 【JOI2017春季合宿】Port Facility

    Description 小M有两个本质不同的栈. 无聊的小M找来了n个玩具.之后小M把这n个玩具随机顺序加入某一个栈或把他们弹出. 现在小M告诉你每个玩具的入栈和出栈时间,现在她想考考小S,有多少种方 ...

  7. UOJ #357. 【JOI2017春季合宿】Sparklers

    Description 小S和小M去看花火大会. 一共有 n 个人按顺序排成一排,每个人手上有一个仅能被点燃一次的烟花.最开始时第 K 个人手上的烟花是点燃的. 烟花最多能燃烧 T 时间.每当两个人的 ...

  8. JOI2017 春季合宿:Railway Trip

    自己的AC做法似乎离正解偏了十万八千里而且复杂了不少--不管怎样还是记录下来吧. 题意: 题目链接: JOISC2017 F - AtCoder JOISC2017 F - LOJ \(N\)个车站排 ...

  9. UOJ356 【JOI2017春季合宿】Port Facility

    暴力就是O(n^2)连边,二分图,这样只有22分. 我们考虑优化建边,我们按照左端点排序,对于一个新加进来的线段,我们向左端点距其最近的和他相交的线段连边,别的相交的我们连同色边,当一个点连了两条同色 ...

随机推荐

  1. Java EE javax.servlet中的ServletConfig接口

    ServletConfig接口 public interface ServletConfig 实现类:GenericServlet.HttpServlet 一.介绍 一个供servlet容器使用配置对 ...

  2. 如何配置数据库镜像<一>

    一.简介 “数据库镜像”是Sql Server 2005推出的一个主要用于提高数据库可用率的软件解决方案.镜像是基于每个数据库执行的,仅适用于使用完整恢复模式的数据库.简单恢复模式和大容量日志恢复模式 ...

  3. DispatcherTimer和Timer的区别

    两者区别是 Timer在非UI线程跑的,DispatcherTimer是在UI线程跑的, DispatcherTimer 可以直接更新UI Timer必须使用this.Dispatcher.Begin ...

  4. 【web性能优化】当用户输入网址后发生了什么?

    简单叙述 这个过程可以大致分为两个部分:网络通信和页面渲染. 一.网络通信 互联网内各网络设备间的通信都遵循TCP/IP协议,利用TCP/IP协议族进行网络通信时,会通过分层顺序与对方进行通信.分层由 ...

  5. Editplus code

    网上一大堆,垃圾也是一大堆,保留一个真正的,提高效率 原文链接:https://blog.csdn.net/anhldd/article/details/85088715 Vovan 3AG46-JJ ...

  6. element-ui Cascader 级联选择器 点击label选中

    通过修改label的样式解决: 注意:el-cascader-panel 是直接挂载在body上的,所以需要全局设置 .el-cascader-panel .el-radio{ width: 100% ...

  7. webconfig中的&符号问题解决

    第一种解决方案 解决方法是将“&”,用“*”代替,取的时候再替换 第二种解决方案 用“&”替换“&”

  8. JavaMaven【三、常用指令】

    mvn compile --编译,编译后生成target文件,里面包含classes mvn test --执行test,测试后在target下生成reports文件夹,测试报告 mvn packag ...

  9. 使用Django开发简单接口:文章增删改查

    目录 1.一些准备工作 安装django 创建django项目 创建博客应用(app) 2.models.py 3.django admin 登录 创建超级用户 4.修改urls.py 5.新增文章接 ...

  10. Samba set of user authentication and file access rights

    This series is compatible with Linux certification exam LPIC. A typical Linux user-level topics omit ...