老早以前的坑了
貌似好多地方都有这个题
因为每个串都只有一个问号,问号可取0可取1,这就是一个经典的2-SAT模型
但是直接做的话,边数是n2n^2级别的,不过因为是01串,可以用可持久化字典树优化建图(可能也可以不可持久化,但是我觉得可持久化比较方便)

UPD:代码可能是假的,看http://blog.csdn.net/coldef/article/details/78303359

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <map>
#include <ctime>
#include <vector>
#include <stack>
#define N 2000010using namespace std;int n,cnt,g,flg;
int B[N],L[N],R[N],dfn[N],low[N],vis[N],wh[N],len[N],G[N];
char *A[N];
char M[N];
stack<int> S;
struct edge{int t,nx;
}E[N];inline void Insert(int x,int y){E[++cnt].t=y; E[cnt].nx=G[x]; G[x]=cnt;
}
map<string,int> Mp;struct trie{int node[N][3],cnt,enin[N];trie(){ cnt=1; }void insert(char *a,int x,int len){int k=1,i=0;while(i<len){if(node[k][a[i]-'0']) k=node[k][a[i]-'0'];else k=node[k][a[i]-'0']=++cnt;i++;}enin[k]=1;}bool check(char *a,int len){int k=1,i=0;while(i<len){if(node[k][a[i]-'0']) k=node[k][a[i]-'0']; else return false;if(enin[k]) return true;i++;}return true;}
}C;struct itrie{int node[N][3],cnt,enin[N],G[N],g;itrie(){ cnt=1;}void insert(char *a,int x,int len){int k=1,i=0;while(i<len){if(node[k][a[i]-'0']) Insert(node[k][a[i]-'0']+g,cnt+1+g);k=node[k][a[i]-'0']=++cnt;i++;}Insert(k+g,x);enin[k]=1;}void explore(char *a,int x,int len){int k=1,i=0,w=0;while(i<len){k=node[k][a[i]-'0'];if(enin[k]) w=k;i++;}if(w) Insert(x,w+g);}
}D,F;void tarjan(int x){low[x]=dfn[x]=++g; vis[x]=1;S.push(x);for(int i=G[x];i;i=E[i].nx){if(!vis[E[i].t]){tarjan(E[i].t);low[x]=min(low[E[i].t],low[x]);}else if(vis[E[i].t]==1) low[x]=min(low[x],dfn[E[i].t]);}if(low[x]==dfn[x]){++flg;while(1){int w=S.top(); S.pop();vis[w]=2;wh[w]=flg;if(w==x||S.empty()) break;}}
}int main(){scanf("%d",&n);for(int i=1,j;i<=n;i++){scanf("%s",M); len[i]=strlen(M);int tot=++Mp[M];if(tot>3) return puts("NO"),0;A[i]=new char[strlen(M)+5];for(j=0;j<len[i];j++) A[i][j]=M[j];for(j=0;j<len[i];j++) if(A[i][j]=='?') break;if(j==len[i]) B[i]=-1;else B[i]=j;}for(int i=1;i<=n;i++)if(B[i]==-1) if(C.check(A[i],len[i])) return puts("NO"),0;else C.insert(A[i],i,len[i]);for(int i=1;i<=n;i++)if(B[i]!=-1){int k=0;A[i][B[i]]='0';if(C.check(A[i],len[i])) k+=1;A[i][B[i]]='1';if(C.check(A[i],len[i])) k+=2;if(k==3) return puts("NO"),0;if(!k) continue;if(k==1)A[i][B[i]]='1',C.insert(A[i],i,len[i]);elseA[i][B[i]]='0',C.insert(A[i],i,len[i]);B[i]=-1;}D.g=500000; F.g=1000000;for(int i=1;i<=n;i++)if(B[i]!=-1){A[i][B[i]]='0';D.explore(A[i],i<<1|1,len[i]);A[i][B[i]]='1';D.explore(A[i],i<<1,len[i]);A[i][B[i]]='0';D.insert(A[i],i<<1,len[i]);A[i][B[i]]='1';D.insert(A[i],i<<1|1,len[i]);}for(int i=n;i;i--)if(B[i]!=-1){A[i][B[i]]='0';F.explore(A[i],i<<1|1,len[i]);A[i][B[i]]='1';F.explore(A[i],i<<1,len[i]);A[i][B[i]]='0';F.insert(A[i],i<<1,len[i]);A[i][B[i]]='1';F.insert(A[i],i<<1|1,len[i]);}for(int i=2;i<=(n<<1|1);i++)if(!vis[i]) tarjan(i);for(int i=1;i<=n;i++)if(wh[i<<1]==wh[i<<1|1]) return puts("NO"),0;puts("YES");return 0;
}

[(可持久化)字典树 优化建图][2-SAT] LOJ#6036. 雅礼集训 2017 Day4. 编码相关推荐

  1. BZOJ.3218.a + b Problem(最小割ISAP 可持久化线段树优化建图)

    BZOJ UOJ 首先不考虑奇怪方格的限制,就是类似最大权闭合子图一样建图. 对于奇怪方格的影响,显然可以建一条边\((i\to x,p_i)\),然后由\(x\)向\(1\sim i-1\)中权值在 ...

  2. UOJ#77. A+B Problem [可持久化线段树优化建边 最小割]

    UOJ#77. A+B Problem 题意:自己看 接触过线段树优化建图后思路不难想,细节要处理好 乱建图无果后想到最小割 白色和黑色只能选一个,割掉一个就行了 之前选白色必须额外割掉一个p[i], ...

  3. 【CF1045A】A Last chance【贪心】【线段树优化建图】【网络流构造方案】

    题意:有nnn个武器和mmm个飞船,武器有下面三种 从给定的集合SSS中击破一个. 在给定的区间[L,R][L,R][L,R]中击破一个. 对于给定的a,b,ca,b,ca,b,c,选择000个或22 ...

  4. Codeforces 786B Legacy (线段树优化建图)

    Codeforces 786B Legacy (线段树优化建图) 题意:\(n\)个点,有\(3\)种连边操作:1.将\(u\)指向\(v\):2.将\(v\)指向编号在区间\([l,r]\)的点:3 ...

  5. 线段树优化建图详解——区间连边之技巧,吊打紫题之利器

    我们从一道例题开始. CF786B Description Solution 朴素解法: 暴力连边+最短路 对于每次连边操作,我们逐一连边,最后在图上跑一遍单源最短路径算法即可. 时间复杂度 O ( ...

  6. Gym - 102174G 神圣的 F2 连接着我们 (线段树优化建图 + 多源最短路)

    Description 小白非常喜欢玩 "县际争霸" 这款游戏,虽然他的技术并不容乐观."县际争霸" 的地图共有两个县,每个县里各有 n n n 个据点.同一个 ...

  7. [LOJ 6042]「雅礼集训 2017 Day7」跳蚤王国的宰相(树的重心+贪心)

    [LOJ 6042]「雅礼集训 2017 Day7」跳蚤王国的宰相 description solution 一个到所有节点距离和最小的节点 ⇔\Leftrightarrow⇔ 树的重心(满足最重的儿 ...

  8. 数据结构二之线段树Ⅱ——KiKi‘s K-Number,ball,The Child and Sequence,「雅礼集训 2017 Day1」市场,Atlantis

    值域线段树+势能线段树+扫描线 KiKi's K-Number ball The Child and Sequence 「雅礼集训 2017 Day1」市场 Atlantis KiKi's K-Num ...

  9. #6034. 「雅礼集训 2017 Day2」线段游戏 李超树

    #6034. 「雅礼集训 2017 Day2」线段游戏 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统 ...

最新文章

  1. Centos 6.4下 MySQL配置主从服务(集群)
  2. IOS 浏览器端overflow:scroll overflow:auto元素无法滑动bug解决方法整理
  3. mysql锁机制(Innodb引擎)
  4. oracle连接数一直超出,Oracle超出最大連接數問題及解決(…
  5. leetcode485. 最大连续1的个数 *py:“又是一行就解决了,没意思”
  6. std::make_shared<T>/std::make_unique<T>与std::shared_ptr<T>/std::unique_ptr<T>的区别与联系
  7. 特征值分解、奇异值分解、PCA概念整理(转载)
  8. 用python重构策略模式
  9. python二维平面上依次得到(0,0)距离相等的点(x,y)坐标,并打印距离
  10. mongodb 创建用户
  11. python软件下载-python软件下载
  12. android 混淆移除log,关于安卓代码混淆和Release版本中去除Debug信息
  13. 使用Mac通知中心,生活讯息一眼看尽
  14. mysql innodb ibd,mysql innodb 从 ibd 文件恢复表数据
  15. Vulkan::0.0::开始于VulKanSDK(Getting Started with the Vulkan SDK)
  16. 国外量化投资的经典案例
  17. 模式识别与机器学习(国科大2021-2022秋季学期课程)-基础概念及算法
  18. 科斯定理(交易费用足够低,谁用的好就归谁)
  19. 如何免费下载卫星影像图
  20. Vue FSC在线编译代码实时预览@vue/repl

热门文章

  1. 【爬虫】用Selenium+PyQuery爬取京东商城
  2. 基于QT实现的可视化地铁换乘查询系统
  3. 【阿旭机器学习实战】【27】贝叶斯模型:新闻分类实战----CounterVecorizer与TfidVectorizer构建特征向量对比
  4. Foxdisk04-启动原理1
  5. 用c语言输出11位电话号码,用C语言结构体解决 “从键盘输入五个用户的数据,包括姓名和电话号码,要求按姓名排序后,输出用户数据...
  6. 清理专家3月6日更新报告
  7. [CCLS] 《封印者》璀璨巨星时装
  8. 用商务领航行的webservice发送短信
  9. 11892 - ENimEN(博弈)
  10. 【2022研电赛】安谋科技企业命题三等奖:基于自主跟随的无人结账一体化购物车