[(可持久化)字典树 优化建图][2-SAT] LOJ#6036. 雅礼集训 2017 Day4. 编码
老早以前的坑了
貌似好多地方都有这个题
因为每个串都只有一个问号,问号可取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. 编码相关推荐
- BZOJ.3218.a + b Problem(最小割ISAP 可持久化线段树优化建图)
BZOJ UOJ 首先不考虑奇怪方格的限制,就是类似最大权闭合子图一样建图. 对于奇怪方格的影响,显然可以建一条边\((i\to x,p_i)\),然后由\(x\)向\(1\sim i-1\)中权值在 ...
- UOJ#77. A+B Problem [可持久化线段树优化建边 最小割]
UOJ#77. A+B Problem 题意:自己看 接触过线段树优化建图后思路不难想,细节要处理好 乱建图无果后想到最小割 白色和黑色只能选一个,割掉一个就行了 之前选白色必须额外割掉一个p[i], ...
- 【CF1045A】A Last chance【贪心】【线段树优化建图】【网络流构造方案】
题意:有nnn个武器和mmm个飞船,武器有下面三种 从给定的集合SSS中击破一个. 在给定的区间[L,R][L,R][L,R]中击破一个. 对于给定的a,b,ca,b,ca,b,c,选择000个或22 ...
- Codeforces 786B Legacy (线段树优化建图)
Codeforces 786B Legacy (线段树优化建图) 题意:\(n\)个点,有\(3\)种连边操作:1.将\(u\)指向\(v\):2.将\(v\)指向编号在区间\([l,r]\)的点:3 ...
- 线段树优化建图详解——区间连边之技巧,吊打紫题之利器
我们从一道例题开始. CF786B Description Solution 朴素解法: 暴力连边+最短路 对于每次连边操作,我们逐一连边,最后在图上跑一遍单源最短路径算法即可. 时间复杂度 O ( ...
- Gym - 102174G 神圣的 F2 连接着我们 (线段树优化建图 + 多源最短路)
Description 小白非常喜欢玩 "县际争霸" 这款游戏,虽然他的技术并不容乐观."县际争霸" 的地图共有两个县,每个县里各有 n n n 个据点.同一个 ...
- [LOJ 6042]「雅礼集训 2017 Day7」跳蚤王国的宰相(树的重心+贪心)
[LOJ 6042]「雅礼集训 2017 Day7」跳蚤王国的宰相 description solution 一个到所有节点距离和最小的节点 ⇔\Leftrightarrow⇔ 树的重心(满足最重的儿 ...
- 数据结构二之线段树Ⅱ——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 ...
- #6034. 「雅礼集训 2017 Day2」线段游戏 李超树
#6034. 「雅礼集训 2017 Day2」线段游戏 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统 ...
最新文章
- Centos 6.4下 MySQL配置主从服务(集群)
- IOS 浏览器端overflow:scroll overflow:auto元素无法滑动bug解决方法整理
- mysql锁机制(Innodb引擎)
- oracle连接数一直超出,Oracle超出最大連接數問題及解決(…
- leetcode485. 最大连续1的个数 *py:“又是一行就解决了,没意思”
- std::make_shared<T>/std::make_unique<T>与std::shared_ptr<T>/std::unique_ptr<T>的区别与联系
- 特征值分解、奇异值分解、PCA概念整理(转载)
- 用python重构策略模式
- python二维平面上依次得到(0,0)距离相等的点(x,y)坐标,并打印距离
- mongodb 创建用户
- python软件下载-python软件下载
- android 混淆移除log,关于安卓代码混淆和Release版本中去除Debug信息
- 使用Mac通知中心,生活讯息一眼看尽
- mysql innodb ibd,mysql innodb 从 ibd 文件恢复表数据
- Vulkan::0.0::开始于VulKanSDK(Getting Started with the Vulkan SDK)
- 国外量化投资的经典案例
- 模式识别与机器学习(国科大2021-2022秋季学期课程)-基础概念及算法
- 科斯定理(交易费用足够低,谁用的好就归谁)
- 如何免费下载卫星影像图
- Vue FSC在线编译代码实时预览@vue/repl
热门文章
- 【爬虫】用Selenium+PyQuery爬取京东商城
- 基于QT实现的可视化地铁换乘查询系统
- 【阿旭机器学习实战】【27】贝叶斯模型:新闻分类实战----CounterVecorizer与TfidVectorizer构建特征向量对比
- Foxdisk04-启动原理1
- 用c语言输出11位电话号码,用C语言结构体解决 “从键盘输入五个用户的数据,包括姓名和电话号码,要求按姓名排序后,输出用户数据...
- 清理专家3月6日更新报告
- [CCLS] 《封印者》璀璨巨星时装
- 用商务领航行的webservice发送短信
- 11892 - ENimEN(博弈)
- 【2022研电赛】安谋科技企业命题三等奖:基于自主跟随的无人结账一体化购物车