热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【ARC069F】Flags(2SAT,Tarjan,线段树优化建图)

注意:本题的点数可以相比题解优化一半。首先先二分答案。然后判断能否使得两两旗子之间的距离都大于\(mid\)。然后发现这是一个2-SAT问题。2-SAT问题:通俗地说,有\(n\)

注意:本题的点数可以相比题解优化一半。



首先先二分答案。

然后判断能否使得两两旗子之间的距离都大于 \(mid\)

然后发现这是一个 2-SAT 问题。

2-SAT 问题:通俗地说,有 \(n\) 个 bool 变量 \(a_i\),并给出一些形如 \(a_i\oplus a_j=0/1\) 的条件(其中 \(\oplus\) 可以是 \(\operatorname{and}\)\(\operatorname{or}\)\(\operatorname{xor}\)),然后询问满足这组方程的一组解 \(a_i\)

这题同样也给出了一些条件,比如说对于所有的 \(i\)\(x_i\)\(y_i\) 中必须选一个但是不能同时选。同时在 \(mid\) 的约束下,也有一些数不能同时选。

那我们可以设 bool 变量 \(a_i\) 表示取不取 \(x_i\),bool 变量 \(b_i\) 表示取不取 \(y_i\)。那么 \(a_i\)\(b_i\) 不能同时等于 \(\text{true}\),且两者中肯定有一者为 \(\text{true}\),这就可以用 \(a_i\operatorname{xor}b_i=1\) 来表示。

那么这就变成了一个 2-SAT 问题了。

但是这道题只用判断是否有解,也就是可行性。这时可以用 Tarjan 求解:

首先把每一个 bool 变量 \(x\) 拆成两个命题:命题 \(x_0\) 表示 \(x=\text{false}\),命题 \(x_1\) 表示 \(x=\text{true}\)。设命题 \(y\) 的反面是 \(y'\),显然 \(x_0'\) 就是 \(x_1\)

那么显然当 \(x_0\) 成立时,\(x_1\) 不成立;当 \(x_1\) 成立时,\(x_0\) 不成立。而且 \(x_0\)\(x_1\) 之间肯定有一者成立。

那么 \(a_i\operatorname{xor}b_i=1\) 就等价于:

\(a_{i,0}\) 成立时,\(b_{i,1}\) 成立;当 \(b_{i,1}\) 成立时,\(a_{i,0}\) 成立。

\(a_{i,1}\) 成立时,\(b_{i,0}\) 成立;当 \(b_{i,0}\) 成立时,\(a_{i,1}\) 成立。

考虑用图论的方式来表达这种关系。

设单向边 \((u,v)\) 表示当命题 \(u\) 成立时,命题 \(v\) 也必定成立。

那么上述关系就可以表示成单向边 \((a_{i,0},b_{i,1})\)\((b_{i,1},a_{i,0})\)\((a_{i,1},b_{i,0})\)\((b_{i,0},a_{i,1})\)

然后题目中还有一些条件:某两个数不能同时取,即某两个 bool 变量 \(a\)\(b\) 不能同时为 \(1\),即 \(a\operatorname{and} b=0\),考虑也用图论来表示这个。

发现可以用有向边 \((a_1,b_0)\)\((b_1,a_0)\) 来表示。

那么我们就能把所有的条件都用图来表示了。

至于如何判断解的可行性:

我们可以先对这个图做一遍 Tarjan,然后看是否存在两个反命题在一个环中(即出现 “当命题 \(x\) 成立时,可得命题 \(x'\) 成立,当 \(x'\) 成立时,也可得 \(x\) 成立,但 \(x\)\(x'\) 为相反的命题” 这种情况)。如果存在,那么原方程无解,否则有解。

然后这道题需要用线段树优化建图才能过。

代码如下:

//1~n 取x[i]
//n+1~2n 取y[i]
//2n+1~3n 不取x[i]
//3n=1~4n 不取y[i]
#include
#define N 20010
using namespace std;
struct data
{
int val,id;
data(){};
data(int a,int b){val=a,id=b;}
}a[N<<1];
int n;
int node,id[N<<3];
int idx,dfn[N*12],low[N*12];
int top,sta[N*12];
int tot,num[N*12];
int cnt,head[N*12],to[N*44],nxt[N*44];
bool ins[N*12];
bool cmp(data a,data b)
{
return a.val}
void adde(int u,int v)
{
to[++cnt]=v;
nxt[cnt]=head[u];
head[u]=cnt;
}
void build(int k,int l,int r)
{
if(l==r)
{
id[k]=(n<<1)+a[l].id;
return;
}
id[k]=++node;
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
adde(id[k],id[k<<1]);
adde(id[k],id[k<<1|1]);
}
void link(int k,int l,int r,int ql,int qr,int rt)
{
if(ql<=l&&r<=qr)
{
adde(rt,id[k]);
return;
}
int mid=(l+r)>>1;
if(ql<=mid) link(k<<1,l,mid,ql,qr,rt);
if(qr>mid) link(k<<1|1,mid+1,r,ql,qr,rt);
}
void Tarjan(int u)
{
dfn[u]=low[u]=++idx;
sta[++top]=u;
ins[u]=true;
for(int i=head[u];i;i=nxt[i])
{
int v=to[i];
if(!dfn[v])
{
Tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(!num[v])
low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u])
{
tot++;
int v;
do
{
v=sta[top];
top--;
ins[v]=false;
num[v]=tot;
}while(u!=v);
}
}
bool check(int mid)
{
cnt=idx=tot=0,node=n<<2;
memset(head,0,sizeof(head));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(num,0,sizeof(num));
build(1,1,n<<1);
for(int i=1;i<=n;i++)
{
adde(i,n+(n<<1)+i);//取x[i]则不取y[i]
adde(n+(n<<1)+i,i);//不取y[i]则取x[i]
adde(n+i,(n<<1)+i);//取y[i]则不取x[i]
adde((n<<1)+i,n+i); //不取x[i]则取y[i]
}
int nowl=1,nowr=1;
for(int i=1;i<=(n<<1);i++)
{
while(nowl=mid) nowl++;
while(nowr<(n<<1)&&a[nowr+1].val-a[i].val if(nowl if(nowr>i) link(1,1,n<<1,i+1,nowr,a[i].id);
}
for(int i=1;i<=(n<<1);i++)
if(!dfn[i])
Tarjan(i);
for(int i=1;i<=(n<<1);i++)
if(num[i]==num[i+(n<<1)])
return false;
return true;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a[i].val,&a[n+i].val);
a[i].id=i,a[n+i].id=n+i;
}
sort(a+1,a+(n<<1)+1,cmp);
int l=0,r=1e9,ans;
while(l<=r)
{
int mid=(l+r)>>1;
if(check(mid)) ans=mid,l=mid+1;
else r=mid-1;
}
printf("%d\n",ans);
return 0;
}


推荐阅读
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • PHP玩家基地系统毕业设计(附源码、运行环境)的用户登录界面、游戏管理和玩家作品管理
    本文介绍了一个PHP玩家基地系统的毕业设计,包括用户登录界面、游戏管理和玩家作品管理等功能。附带源码和运行环境,并提供免费赠送本源代码和数据库的方式,请私信获取详细信息。摘要共计约XXX字。 ... [详细]
  • 本文描述了作者第一次参加比赛的经历和感受。作者是小学六年级时参加比赛的唯一选手,感到有些紧张。在比赛期间,作者与学长学姐一起用餐,在比赛题目中遇到了一些困难,但最终成功解决。作者还尝试了一款游戏,在回程的路上感到晕车。最终,作者以110分的成绩取得了省一会的资格,并坚定了继续学习的决心。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • PHP图片截取方法及应用实例
    本文介绍了使用PHP动态切割JPEG图片的方法,并提供了应用实例,包括截取视频图、提取文章内容中的图片地址、裁切图片等问题。详细介绍了相关的PHP函数和参数的使用,以及图片切割的具体步骤。同时,还提供了一些注意事项和优化建议。通过本文的学习,读者可以掌握PHP图片截取的技巧,实现自己的需求。 ... [详细]
  • 关羽败走麦城时路过马超封地 马超为何没有出手救人
    对当年关羽败走麦城,恰好路过马超的封地,为啥马超不救他?很感兴趣的小伙伴们,趣历史小编带来详细的文章供大家参考。说到英雄好汉,便要提到一本名著了,没错,那就是《三国演义》。书中虽 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • PHP设置MySQL字符集的方法及使用mysqli_set_charset函数
    本文介绍了PHP设置MySQL字符集的方法,详细介绍了使用mysqli_set_charset函数来规定与数据库服务器进行数据传送时要使用的字符集。通过示例代码演示了如何设置默认客户端字符集。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 橱窗设计的表现手法及其应用
    本文介绍了橱窗设计的表现手法,包括直接展示、寓意与联想、夸张与幽默等。通过对商品的折、拉、叠、挂、堆等陈列技巧,橱窗设计能够充分展现商品的形态、质地、色彩、样式等特性。同时,寓意与联想可以通过象形形式或抽象几何道具来唤起消费者的联想与共鸣,创造出强烈的时代气息和视觉空间。合理的夸张和贴切的幽默能够明显夸大商品的美的因素,给人以新颖奇特的心理感受,引起人们的笑声和思考。通过这些表现手法,橱窗设计能够有效地传达商品的个性内涵,吸引消费者的注意力。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • faceu激萌变老特效的使用方法详解
    本文介绍了faceu激萌变老特效的使用方法,包括打开faceu激萌app、点击贴纸、选择热门贴纸中的变老特效,然后对准人脸进行拍摄,即可给照片添加变老特效。操作简单,适合新用户使用。 ... [详细]
author-avatar
白人冰娟
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有