Binary_Code 2-SAT神题

来源:互联网 发布:51单片机项目外包网 编辑:程序博客网 时间:2024/06/05 14:20

Problem B. Binary Code
Input file: binary.in
Output file: binary.out
Ben has recently learned about binary prefix codes. A binary code is a set of n distinct nonempty code
words si
, each consisting of 0s and 1s. A code is called a prefix code if for every i 6= j neither si
is a prefix
of sj nor sj is a prefix of si
. A word x is called a prefix of a word w if there exists a possibly empty word
y, such that xy = w. For example, x = 11 is a prefix of w = 110 and x = 0100 is a prefix of w = 0100.
Ben found a paper with n lines of binary code in it. However, this paper is pretty old and there are some
unreadable characters. Fortunately, each word contains at most one unreadable character.
Ben wants to know whether these n lines could represent a binary prefix code. In other words, can he
replace every unreadable character with 0 or 1, so that the code becomes a prefix code?
Input
The first line contains integer n — the number of code words (1 ≤ n ≤ 5 · 105
).
Next n lines contain nonempty code word records, one per line. Each code word record consists of “0”,
“1” and “?” characters. Every code word record contains at most one “?” character that represents
unreadable character.
The total length of words does not exceed 5 · 105
.
Output
Output “NO” in the first line if the code cannot be a prefix code.
Otherwise, output “YES” in the first line. Next n lines shall contain code words in the same order as the
corresponding code word records in the input.
If there are several prefix codes, that could have been written on the paper, output any one.
Examples
binary.in binary.out
4
00?
0?00
?1
1?0
YES
000
0100
11
100
3
0100
01?0
01?0
NO

http://codeforces.com/gym/101190/attachments/download/4956/20162017-acmicpc-northeastern-european-regional-contest-neerc-16-en.pdf
题面.
早就听orbitingflea大佬说起此题了,今天终于将其AC了.

trie树优化2-SAT建图:

Trie树优化建图的精髓是利用原图前缀或后缀的性质,利用节点与子树的关系优化建图.遇到这类字符串前缀后缀以及图论相关的题可以往Trie树这一方面想

trie树上往x的1连边往其父亲的0连边这个限制一开始没想到,Trie图优化建边要满足严格子树2-SAT的trick.

第二个trick,在判断两个相同串时需要判断一个集合内最多有一个元素出现一次的Trick,其trick是新建前缀优化建边.当前点与其对应前一个的前缀互斥,前缀维护前缀or,然后当前点能推出当前前缀点.这样能O(n)满足条件.2-SAT建边Trick

第三个Trick是orbitingflea大佬所说的2-SAT输出方案用tarjan的话对于每个点直接选择scc_no小的那个就能保证正确性,具体证明见orbitingflea博客.

发现理清思路加长变量名思维会清晰很多,以后做题也要这样.

原创粉丝点击