传送门

题意简述

判定 n 个含 ? 字符的二进制串是否存在一种把 0/1 填入 ? 中的方案使得任意两个串不具有前缀关系。

(一个串最多一个 ?)

Sol

二进制串 ,并且一个串最多一个 '?'

很容易想到用 2-sat 和 trie 树。

那么问题变为插入这些二进制串,在 ‘?’ 处选择向哪边插入 ,使得任意一个结束节点的祖先节点中不存在一个结束节点。

然后我们考虑构建 2-sat 模型,首先每一个串分配一个变量表示 '?' 选择了什么(没有?就随便强制选则某一个就行了)

当然之后我们一种思路是直接用这些变量来判定并解决问题 ,不过复杂度显然是 \(O(n^2)\) 的。

考虑优化,因为是祖先中不能存在结束节点,我们给每一个 trie 树上的节点加一个变量表示除去自己外的祖先中是否存在结束节点,这个东西显然从上到下具有传递性,那么可以初步建图了。

然后看怎么体现一个串的 '?' 的决策情况。发现这个东西不是很好做,因为结束节点不会受到自己影响。那么我们直接新建一个变量好了,表示包含了当前位置的情况下祖先是否有结束节点。

之后我们还需要解决一个问题,就是一些不同的串可能共用了结束位置,我们显然不能够让他们共用一个变量,因为他们之间也是互相影响的,并且他们还来自不同的 '?' ,不能共用。

发现这个东西可以直接和上面的情况合并到一个变量上,因为本来我们插入完之后就要新建一个点,那么正好一起用,也不影响答案,把该连的边连上就行了。

code:

#include<bits/stdc++.h>
using namespace std;
template<class T>inline void init(T&x){
x=0;char ch=getchar();bool t=0;
for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') t=1;
for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+(ch-48);
if(t) x=-x;return;
}
#define TR(a) ((a)<<1|1)
#define FA(a) ((a)<<1)
const int N=5e5+10;
const int MAXN=3e6+10;
int son[MAXN][2];
char S[N];
char *s[N];int len[N],id[N];
int n,cnt=0;
inline bool cmp(int i,int j){return len[i]<len[j];}
struct edge{
int to,next;
}a[MAXN];
int head[MAXN],cur=0,dfn[MAXN],low[MAXN],bel[MAXN],stk[MAXN],top=0,vis[MAXN],I=0,bcc;
inline void add(int x,int y){a[++cur]=(edge){y,head[x]};head[x]=cur;}
void tarjan(int u){
dfn[u]=low[u]=++I,stk[++top]=u,vis[u]=1;
for(int v,i=head[u];i;i=a[i].next){
v=a[i].to;
if(!dfn[v]) tarjan(v),low[u]=min(low[u],low[v]);
else if(vis[v]) low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u]) {
int v;++bcc;
do{v=stk[top--];vis[v]=0;bel[v]=bcc;if(bel[v]==bel[v^1]) {puts("NO"),exit(0);}}while(v!=u);
}
return;
}
void Insert(char*s,int len,int Jud){
int p=0,las=0;
for(int i=1;i<=len;++i) {
int c=s[i]-'0';
las=p;
if(son[p][c]) p=son[p][c];
else {
son[p][c]=++cnt;
if(p) add(TR(p),TR(cnt)),add(FA(cnt),FA(p));
p=cnt;
}
}
++cnt;//新建点以防止出现多个串共用了一个点的情况 , 新建的点是要考虑当前点的!
add(Jud,FA(p)),add(TR(p),Jud^1);
add(TR(p),TR(cnt)),add(FA(cnt),FA(p));
add(Jud,TR(cnt)),add(FA(cnt),Jud^1);
son[las][(int)(son[las][1]==p)]=cnt;
}
int main()
{
init(n);int now=1;cnt=n;// n 个串选择什么
for(int i=1;i<=n;++i){
scanf("%s",S+now);
len[i]=strlen(S+now);
s[i]=&S[now-1];now+=len[i];
id[i]=i;
}sort(id+1,id+1+n,cmp);
for(int i=1;i<=n;++i) {
int t=id[i];int j=0;
for(j=1;j<=len[t];++j) {
if(s[t][j]=='?') {// 有问号
s[t][j]='0';Insert(s[t],len[t],FA(t));//填 0
s[t][j]='1';Insert(s[t],len[t],TR(t));//填 1
break;
}
}
if(j>len[t]) {add(TR(t),FA(t));Insert(s[t],len[t],FA(t));}
}
for(int i=0;i<=cnt;++i) if(!dfn[i]) tarjan(i);
puts("YES");
return 0;
}

【LOJ#6036】[雅礼集训2017Day4]编码的更多相关文章

  1. LOJ.6504.[雅礼集训2018 Day5]Convex(回滚莫队)

    LOJ 莫队.发现只需要维护前驱后继就可以了. 但是加入一个点需要找到它当前的前驱后继,很麻烦还带个\(\log\). 但是如果只有删除某个点,只需要更新一下它的前驱后继即可. 用回滚莫队就好惹. 撤 ...

  2. Loj#6503-「雅礼集训 2018 Day4」Magic【分治NTT】

    正题 题目链接:https://loj.ac/p/6503 题目大意 \(n\)张卡\(m\)种,第\(i\)种卡有\(a_i\)张,求所有排列中有\(k\)对相邻且相同的卡牌. \(1\leq n\ ...

  3. $loj\ 6045$ [雅礼集训 $2017\ Day8$] 价 网络流

    正解:网络流 解题报告: 传送门$QwQ$ 这题还,挺有趣的我$jio$得. 考虑依然先是照着最小割的模子建图呗,然后从意义上来分析,割一条边就相当于不吃一种减肥药/买一种药材.由已知得,买的药材数量 ...

  4. [LOJ 6031]「雅礼集训 2017 Day1」字符串

    [LOJ 6031] 「雅礼集训 2017 Day1」字符串 题意 给定一个长度为 \(n\) 的字符串 \(s\), \(m\) 对 \((l_i,r_i)\), 回答 \(q\) 个询问. 每个询 ...

  5. [LOJ 6030]「雅礼集训 2017 Day1」矩阵

    [LOJ 6030] 「雅礼集训 2017 Day1」矩阵 题意 给定一个 \(n\times n\) 的 01 矩阵, 每次操作可以将一行转置后赋值给某一列, 问最少几次操作能让矩阵全为 1. 无解 ...

  6. [LOJ 6029]「雅礼集训 2017 Day1」市场

    [LOJ 6029] 「雅礼集训 2017 Day1」市场 题意 给定一个长度为 \(n\) 的数列(从 \(0\) 开始标号), 要求执行 \(q\) 次操作, 每次操作为如下四种操作之一: 1 l ...

  7. Loj #6503. 「雅礼集训 2018 Day4」Magic

    Loj #6503. 「雅礼集训 2018 Day4」Magic 题目描述 前进!前进!不择手段地前进!--托马斯 · 维德 魔法纪元元年. 1453 年 5 月 3 日 16 时,高维碎片接触地球. ...

  8. loj #6046. 「雅礼集训 2017 Day8」爷

    #6046. 「雅礼集训 2017 Day8」爷 题目描述 如果你对山口丁和 G&P 没有兴趣,可以无视题目背景,因为你估计看不懂 …… 在第 63 回战车道全国高中生大赛中,军神西住美穗带领 ...

  9. LOJ_6045_「雅礼集训 2017 Day8」价 _最小割

    LOJ_6045_「雅礼集训 2017 Day8」价 _最小割 描述: 有$n$种减肥药,$n$种药材,每种减肥药有一些对应的药材和一个收益. 假设选择吃下$K$种减肥药,那么需要这$K$种减肥药包含 ...

随机推荐

  1. http-server 建立 HTTPS 服务

    1. 创建证书 进入要建立 HTTPS 服务的目录 openssl genrsa -out key.pem 1024 openssl req -new -key key.pem -out csr.pe ...

  2. 搜索引擎、邮件营销、微信营销之营销方式大PK

    经常有朋友问到这个问题,关于搜索引擎.邮件营销.微信营销三种网络营销方式的优劣势,用哪种营销方式比较好.下面我们跟随Focussend小编来看看这几种方式的优劣势. 搜索引擎 优势:1.传播速度快:2 ...

  3. 如何将EDM数据分类工作做的更加真善美

    众所周知,数据是互联网时代营销的决定性因素,数据的好坏关乎到营销能力的强弱,而细化到EDM行业中,数据细分变得极为重要,根据数据形态的不同,将会涉及到多种不同的细分方法,有效的利用这些方法,将会大大的 ...

  4. python对象的引用

    1 利用 * 星号生成二维及二维以上的list时,特别要注意有的量引用是相同的.如果后面要给list赋值,最好不要这样生成list. 可以先这样生成,再打印输出后,粘贴到程序中重新赋值. a = [[ ...

  5. Lua增加一个节点到文件中

    新建一个文件touch /etc/config/ddns 增加一个节点到文件中uci set ddns.newadd=config <config>:即配置文件,如ddns,ipv6等&l ...

  6. 算法之美&数据结构与算法复习

    1.归并两个有序链表(归并排序) 2.最小路径和--BP解法 3.计算int sqrt(x)--二分解法 4.趣味面试题 5.跳步游戏(Jump_Game)--后向回溯算法 6.Excel列号转十进制 ...

  7. 深入理解Linux-hostname

    当我觉得对Linux系统下修改hostname已经非常熟悉的时候,今天碰到了几个个问题,这几个问题给我好好上了一课,很多知识点,当你觉得你已经掌握的时候,其实你了解的还只是皮毛.技术活,切勿浅尝则止! ...

  8. python面试题--初级(一)

    一. Python 中有多少种运算符? 这类面试问题可以判断你的 Python 功底,可以举一些实例来回答这类问题. 在 Python 中我们有 7 中运算符: 算术运算符.关系 (比较) 运算符.赋 ...

  9. 【Linux 架构】Linux内核架构

    (1)System Call Interface(SCI)------系统调用接口(2)Process Management(PM)-------进程管理模块(3)Memory Management( ...

  10. springboot 整合 tobato 的 fastdfs 实现文件上传和下载

    添加项目所需要的依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId ...