【LOJ6036】编码(2-sat)

题面

LOJ

题解

很显然的一个暴力:

枚举每个串中的?是什么,然后把和它有前缀关系的串全部给找出来,不合法的连边处理一下,那么直接跑\(2-sat\)就做完了。

现在的问题就在与不合法的数量可能会很多,所以需要优化这个连边的过程。

显然前缀关系和\(Trie\)树上的节点是相关的,即\(Trie\)树上这个串路径上所代表的所有点都是它的前缀,其子树中的每个串都以当前串为前缀。

首先构建\(Trie\),在往下的过程中对于路径上的所有已知前缀连边,这里肯定不能暴力一个个连,考虑把所有结尾的位置全部挂一条链挂在\(Trie\)树的这个节点上,那么只需要一路连下来就好了。

这样子就处理完了当前串的前缀。

但是当前串加入进来之后还可能会作为后面串的前缀,所以也要类似的挂在\(Trie\)树上。

连边的时候顺便处理好逆否命题的连边,这样子就不用建两次边了。

注意一下实际上这里需要两棵\(Trie\)树,一棵从上往下连,一棵从下往上连。

实际处理的时候把\(Trie\)树也建立正反两个点直接当做逆否命题连边就好了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAX 3000300
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
struct Line{int v,next;}e[MAX<<1];
int h[MAX],cnt=2;
inline void Add(int u,int v)
{
e[cnt]=(Line){v,h[u]};h[u]=cnt++;
u^=1;v^=1;
e[cnt]=(Line){u,h[v]};h[v]=cnt++;
}
int dfn[MAX],low[MAX],tim,G[MAX],scc;
int S[MAX],top;bool ins[MAX];
string s[MAX];
void Tarjan(int u)
{
dfn[u]=low[u]=++tim;ins[u]=true;S[++top]=u;
for(int i=h[u];i;i=e[i].next)
if(!dfn[e[i].v])Tarjan(e[i].v),low[u]=min(low[u],low[e[i].v]);
else if(ins[e[i].v])low[u]=min(low[u],dfn[e[i].v]);
if(dfn[u]==low[u])
{
++scc;int v;
do{v=S[top--];ins[v]=false;G[v]=scc;}while(u!=v);
}
}
int son[MAX][2],tot;
int n,len[MAX],p[MAX];
char ch[MAX];
void Insert(int u,int p)
{
int x=n+1,lst=0;
for(int i=0;i<len[u];++i)
{
if(!son[x][s[u][i]-48])son[x][s[u][i]-48]=++tot;
lst=x;x=son[x][s[u][i]-48];Add(p,x<<1);
}
int y=++tot;
Add(p,y<<1|1);Add(y<<1,x<<1);
son[lst][s[u][len[u]-1]-48]=y;
}
bool cmp(int a,int b){return len[a]<len[b];}
int main()
{
n=read();
for(int i=1;i<=n;++i)
{
scanf("%s",ch);len[i]=strlen(ch);p[i]=i;
for(int j=0;j<len[i];++j)s[i]+=ch[j];
}
sort(&p[1],&p[n+1],cmp);tot=n+1;
for(int i=1;i<=n;++i)
{
int u=p[i];
for(int j=0;j<len[u];++j)
if(s[u][j]=='?')
{
s[u][j]=48;Insert(u,u<<1);
s[u][j]=49;Insert(u,u<<1|1);
break;
}
else if(j==len[u]-1)Insert(u,u<<1),Add(u<<1|1,u<<1);
}
for(int i=1;i<=(tot<<1|1);++i)if(!dfn[i])Tarjan(i);
for(int i=1;i<=tot;++i)if(G[i<<1]==G[i<<1|1]){puts("NO");return 0;}
puts("YES");
return 0;
}

【LOJ6036】编码(2-sat)的更多相关文章

  1. LOJ6036 编码 2-SAT、Trie

    传送门 每个串只有一个?,?还只能填0或者1,不难想到2-SAT求解. 一个很暴力的想法是枚举?填0或者1,然后对所有可能的前缀连边.这样边数是\(O(n^2)\)的,需要优化. 看到前缀不难想到Tr ...

  2. LOJ6036编码

    每个串拆成两个,都插入trie数. 把trie树建出来后,每一条从根到叶子的链上最多只能有一个变量为1. 这是个经典的前后缀优化2-sat建图的套路. 树上的做法也就是边dfs边做而已. #inclu ...

  3. 前端笔记之服务器&Ajax(上)服务器&PHP&数据交互&HTTP

    一.服务器 1.1 什么是服务器,做什么的? 服务器,就是放在机房中的电脑,和我们的电脑的区别在与服务器有固定的IP,服务器的安全性和稳定性相当的高;性能一般就可以了,但是CPU的性能要比普通的客户机 ...

  4. [LOJ6029~6052]雅礼集训 2017 选做

    Link 代码可以在loj上看我的提交记录. Day 1 [LOJ6029]市场 对于一次除法操作,若区间内所有数的减少量均相同则可视作区间减法,否则暴力递归下去.显然一个线段树节点只会被暴力递归进去 ...

  5. 【LOJ6036】 「雅礼集训 2017 Day4」编码

    传送门 LOJ Solution 因为?只有两种可能为0,1,所以就把这两个串搞出来. 那么现在?取0和?取1不能并存,前缀不能并存,所以就是一个\(2-SAT\),现在问题在于这个东西可能会有很多条 ...

  6. 前端学HTTP之实体和编码

    前面的话 每天都有各种媒体对象经由HTTP传送,如图像.文本.影片以及软件程序等.HTTP要确保它的报文被正确传送,识别.提取以及适当处理.为了实现这些目标,HTTP使用了完善的标签来描述承载内容的实 ...

  7. 2.keras实现-->字符级或单词级的one-hot编码 VS 词嵌入

    1. one-hot编码 # 字符集的one-hot编码 import string samples = ['zzh is a pig','he loves himself very much','p ...

  8. (转)x264 编码流程

    转自:http://alphamailpost.blog.163.com/blog/static/20111808120128111160728/ http://www.usr.cc/thread-5 ...

  9. 服务器返回中文乱码的情况(UTF8编码 -> 转化为 SYSTEM_LOCALE 编码)

    服务器乱码 转换使用如下方法 入惨{“msg”} -> utf8编码 -> 转化为 SYSTEM_LOCALE 编码 -> 接受转换后的参数 "sEncoding" ...

随机推荐

  1. 初用Ajax

    早就有学习Ajax的想法了,但每次拿起一本Ajax的书,翻了不到百页就学不下去了,里面讲的东西实在太多了,前面讲javaScript的内容看了好 几遍都记不住,也就没心思去看后面的内容:看Ajax案例 ...

  2. semantic-ui 图片

    1.基础样式 方式一:因为图片是使用img标签,所以直接将class加载img标签中即可.不过要注意的是,class中要指定是ui image. 方式二:使用一个span或者div将img标签包裹,然 ...

  3. Mission Impossible 6

    题目:Mission Impossible 6 题目链接:http://hihocoder.com/problemset/problem/1228 题目大意: 大概就是让我们写一个代码模拟文本编辑器的 ...

  4. Spring boot 将配置文件属性注入到一个bean中

    现在要做的就是将如下配置文件中的内容注入到一个bean 名为Properties中. Redis.properties配置文件中的内容如下: Properties java bean中代码如下,注意注 ...

  5. Codeforces 1154G Minimum Possible LCM

    题目链接:http://codeforces.com/problemset/problem/1154/G 题目大意: 给定n个数,在这些数中选2个数,使这两个数的最小公倍数最小,输出这两个数的下标(如 ...

  6. hadoop 管理命令dfsadmin

    hadoop 管理命令dfsadmin dfsadmin 命令用于管理HDFS集群,这些命令常用于管理员. 1. (Safemode)安全模式 动作 命令 把集群切换到安全模式 bin/hdfs df ...

  7. python之路--面向对象-成员

    一 . 成员 在类中你能写的所有内容都是类的成员 class 类名: # 方法 def__init__(self, 参数1, 参数2...): # 属性变量 self.属性1 = 参数1 self.属 ...

  8. Golang的时间生成,格式化,以及获取函数执行时间的方法

    最近都在通过完成一些列功能强化自己对常用api的熟悉. 然而关于时间的api几乎是最常用的api类型,所以总结一些常用的. 以YY-mm-dd HH:MM:SS.9位 输出当前时间: func mai ...

  9. python设计模式第六天【原型模式】

    1.定义 使用原型模式复制的对象与原来对象具有一样的结构和数据,有浅克隆和深克隆 2.应用场景 (1)希望复制原来对象的结构和数据胆步影响原来对象 3.代码实现 #!/usr/bin/env pyth ...

  10. ubuntu 完全卸载mysql

    卸载 sudo apt-get --purge remove mysql-common -y sudo apt-get --purge remove mysql* -y sudo apt-get au ...