LOJ #6036.「雅礼集训 2017 Day4」编码 Trie树上2-sat
记得之前做过几道2-sat裸体,以及几道2-sat前缀优化建图,这道题使用了前缀树上前缀树优化建图.
我们暴力建图肯定是n^2级别的,那么我们要是想让边数少点,就得使用一些骚操作.
我们观察我们的限制条件,不就是选了一个点,那么这个点的前缀都不能选吗(选了一个点,以他为前缀的的点也不能选,这个限制条件可以通过前面那个限制条件体现出来,所以说观察到问题本质是一样的,可以简化我们的问题).那么我们就可以在Trie上建图,使得选择一个点,那么他的前缀点都必须不能选,就可以了.但是对于一个点上有多个点的情况,我们要特殊处理,我的处理方法是,把那些点拽出来作为树点.
最后说一下,要注意2-sat建图一定要连逆否命题边.
(感觉自己2-sat好虚啊……)
语言笔记:
exit(0),只要你在程序中使用,无论在哪里,直接正常退出,具体情况见http://blog.csdn.net/u010046690/article/details/47105665
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
const int N=;
struct V{
int to,next;
}c[N<<];
int head[N<<],t;
inline void add(int x,int y){
c[++t].to=y,c[t].next=head[x],head[x]=t;
}
char s[N],*begin[N];
int n,len[N],m;
int pos[N],temp[N];
int dfn[N<<],low[N<<],belong[N<<],stack[N<<],top,num,Ti;
bool in[N<<];
inline void Tarjan(int x){
dfn[x]=low[x]=++Ti;
stack[++top]=x;
in[x]=true;
register int i;
for(i=head[x];i;i=c[i].next)
if(!dfn[c[i].to]){
Tarjan(c[i].to);
low[x]=std::min(low[x],low[c[i].to]);
}else if(in[c[i].to])
low[x]=std::min(low[x],dfn[c[i].to]);
if(low[x]==dfn[x]){
++num;
register int j;
do{
j=stack[top--];
in[j]=false;
belong[j]=num;
}while(j!=x);
}
}
#define choose(a,b) (((a)<<1)-(b))
struct Trie{
Trie *ch[];
std::vector<int> mem;
Trie(){ch[]=ch[]=NULL,mem.clear();}
inline void* operator new(size_t);
}*root,*C,*mempool;
inline void* Trie::operator new(size_t){
if(C==mempool){
C=new Trie[(<<)+];
mempool=C+(<<)+;
}
return C++;
}
inline void build(Trie *p,int id){
register int i,x,a,b,size=p->mem.size();
if(!size)return;
for(i=;i<size;++i){
x=p->mem[i];
if((pos[x]==-&&pos[id]==-)||(pos[x]==-&&pos[id]>=len[x])){
puts("NO");
exit();
}
if(pos[x]==pos[id]){
add(choose(x,),choose(id,));
add(choose(x,),choose(id,));
add(choose(id,),choose(x,));
add(choose(id,),choose(x,));
}else{
if(pos[id]==-||pos[id]>=len[x]){
if(begin[id][pos[x]]==''){
add(choose(x,),choose(x,));
}else{
add(choose(x,),choose(x,));
}
}else{
if(pos[x]==-){
if(begin[x][pos[id]]==''){
add(choose(id,),choose(id,));
}else{
add(choose(id,),choose(id,));
}
}else{
a=begin[id][pos[x]]=='';
b=begin[x][pos[id]]=='';
add(choose(x,a),choose(id,b^));
add(choose(id,b),choose(x,a^));
}
}
}
}
}
inline void insert(int id){
register Trie *p=root,*w;
register int i,j,l=len[id];
for(i=;i<l;++i){
if(begin[id][i]=='?'){
if(!p->ch[])
p->ch[]=new Trie();
w=p->ch[];
build(w,id);
for(j=i+;j<l;++j){
if(!w->ch[begin[id][j]-''])
w->ch[begin[id][j]-'']=new Trie();
w=w->ch[begin[id][j]-''];
build(w,id);
}
w->mem.push_back(id);
if(!p->ch[])
p->ch[]=new Trie();
w=p->ch[];
build(w,id);
for(j=i+;j<l;++j){
if(!w->ch[begin[id][j]-''])
w->ch[begin[id][j]-'']=new Trie();
w=w->ch[begin[id][j]-''];
build(w,id);
}
w->mem.push_back(id);
return;
}
if(!p->ch[begin[id][i]-''])
p->ch[begin[id][i]-'']=new Trie();
p=p->ch[begin[id][i]-''];
build(p,id);
}
p->mem.push_back(id);
}
inline bool comp(int x,int y){
return len[x]<len[y];
}
inline void Init(){
root=new Trie();
scanf("%d",&n);
register int i,j;
for(i=;i<=n;++i){
pos[i]=-;
begin[i]=s+m;
scanf("%s",s+m);
len[i]=strlen(s+m);
m+=len[i];
temp[i]=i;
for(j=;j<len[i];++j)
if(begin[i][j]=='?'){
pos[i]=j;
break;
}
}
std::sort(temp+,temp+(n+),comp);
for(i=;i<=n;++i){
insert(temp[i]);
}
}
inline bool check(){
register int i;
for(i=;i<=(n<<);++i)
if(!dfn[i])
Tarjan(i);
for(i=;i<=n;++i)
if(belong[choose(i,)]==belong[choose(i,)])
return false;
return true;
}
int main(){
//freopen("rio.in","r",stdin);
Init();
puts(check()?"YES":"NO");
return ;
}
88分暴力
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define R register
const int N=;
struct V{int to,next;}c[N<<];
int head[N*],t;
inline void add(int x,int y){
c[++t].to=y,c[t].next=head[x],head[x]=t;
}
char s[N];
int n,cnt;
int dfn[N*],low[N*],belong[N*],stack[N*],top,num,Ti;
bool in[N*];
inline void Tarjan(int x){
dfn[x]=low[x]=++Ti;
stack[++top]=x;
in[x]=true;
R int i;
for(i=head[x];i;i=c[i].next)
if(!dfn[c[i].to]){
Tarjan(c[i].to);
low[x]=std::min(low[x],low[c[i].to]);
}else if(in[c[i].to])
low[x]=std::min(low[x],dfn[c[i].to]);
if(low[x]==dfn[x]){
++num;
do{
i=stack[top--];
in[i]=false;
belong[i]=num;
}while(i!=x);
}
}
#define H(a,b) (((a)<<1)-(b))
struct Trie{
Trie *ch[];
std::vector<int> mem;
Trie(){ch[]=ch[]=NULL,mem.clear();}
inline void* operator new(size_t);
}*root,*C,*mempool;
inline void* Trie::operator new(size_t){
if(C==mempool){
C=new Trie[(<<)+];
mempool=C+(<<)+;
}
return C++;
}
inline void dfs(Trie *p,int fa){
if(!p)return;
R int i,j,x,last=fa,size=p->mem.size();
for(i=;i<size;++i){
x=p->mem[i];
++cnt;
if(x>)j=;
else x=-x,j=;
add(H(x,j),H(cnt,));
add(H(cnt,),H(x,j^));
add(H(x,j),H(last,));
add(H(last,),H(x,j^));
add(H(cnt,),H(last,));
add(H(last,),H(cnt,));
last=cnt;
}
++cnt;
if(last){
add(H(cnt,),H(last,));
add(H(last,),H(cnt,));
}
last=cnt;
dfs(p->ch[],last);
dfs(p->ch[],last);
}
inline void insert(int id){
scanf("%s",s);
R Trie *p=root,*w;
R int i,j,l=strlen(s);
for(i=;i<l;++i)s[i]-='';
for(i=;i<l;++i){
if(s[i]>){
w=(!p->ch[])?p->ch[]=new Trie():p->ch[];
for(j=i+;j<l;++j)
w=(!w->ch[s[j]])?w->ch[s[j]]=new Trie():w->ch[s[j]];
w->mem.push_back(-id);
w=(!p->ch[])?p->ch[]=new Trie():p->ch[];
for(j=i+;j<l;++j)
w=(!w->ch[s[j]])?w->ch[s[j]]=new Trie():w->ch[s[j]];
w->mem.push_back(id);
return;
}
p=(!p->ch[s[i]])?p->ch[s[i]]=new Trie():p->ch[s[i]];
}
add(H(id,),H(id,));
p->mem.push_back(id);
}
inline bool check(){
R int i;
for(i=;i<=(cnt<<);++i)
if(!dfn[i])Tarjan(i);
for(i=;i<=cnt;++i)
if(belong[H(i,)]==belong[H(i,)])
return false;
return true;
}
int main(){
root=new Trie();
scanf("%d",&n),cnt=n;
R int i;
for(i=;i<=n;++i)insert(i);
dfs(root,);
puts(check()?"YES":"NO");
return ;
}
100分正解
LOJ #6036.「雅礼集训 2017 Day4」编码 Trie树上2-sat的更多相关文章
- Loj 6036 「雅礼集训 2017 Day4」编码 - 2-sat
题目传送门 唯一的传送门 题目大意 给定$n$个串,每个串只包含 ' .问是否可能任意两个不同的串不满足一个是另一个的前缀. 2-sat的是显然的. 枚举每个通配符填0还是1,然后插入Trie树. 对 ...
- loj 6037 「雅礼集训 2017 Day4」猜数列 - 动态规划
题目传送门 传送门 题目大意 有一个位置数列,给定$n$条线索,每条线索从某一个位置开始,一直向左或者向右走,每遇到一个还没有在线索中出现的数就将它加入线索,问最小的可能的数列长度. 依次从左到右考虑 ...
- LOJ #6037.「雅礼集训 2017 Day4」猜数列 状压dp
这个题的搜索可以打到48分…… #include <cstdio> #include <cstring> #include <algorithm> ; bool m ...
- 2018.10.27 loj#6035. 「雅礼集训 2017 Day4」洗衣服(贪心+堆)
传送门 显然的贪心题啊...考试没调出来10pts滚了妙的一啊 直接分别用堆贪心出洗完第iii件衣服需要的最少时间和晾完第iii件衣服需要的最少时间. 我们设第一个算出来的数组是aaa,第二个是bbb ...
- LOJ#6035. 「雅礼集训 2017 Day4」洗衣服
传送门 先处理出每一件衣服最早什么时候洗完,堆+贪心即可 然后同样处理出每件衣服最早什么时候烘干 然后倒序相加取最大值 # include <bits/stdc++.h> using na ...
- LOJ #6035.「雅礼集训 2017 Day4」洗衣服 贪心
这道题的贪心好迷啊~我们对于两个过程进行单独贪心,然后再翻转一个,把这两个拼起来.先说一下单独贪心,单独贪心的话就是用一个堆,每次取出最小的,并且把这个最小的加上他单次的,再放进去.这样,我们得到的结 ...
- 【LOJ6036】 「雅礼集训 2017 Day4」编码
传送门 LOJ Solution 因为?只有两种可能为0,1,所以就把这两个串搞出来. 那么现在?取0和?取1不能并存,前缀不能并存,所以就是一个\(2-SAT\),现在问题在于这个东西可能会有很多条 ...
- [LOJ 6031]「雅礼集训 2017 Day1」字符串
[LOJ 6031] 「雅礼集训 2017 Day1」字符串 题意 给定一个长度为 \(n\) 的字符串 \(s\), \(m\) 对 \((l_i,r_i)\), 回答 \(q\) 个询问. 每个询 ...
- [LOJ 6030]「雅礼集训 2017 Day1」矩阵
[LOJ 6030] 「雅礼集训 2017 Day1」矩阵 题意 给定一个 \(n\times n\) 的 01 矩阵, 每次操作可以将一行转置后赋值给某一列, 问最少几次操作能让矩阵全为 1. 无解 ...
随机推荐
- 3.5星|《哈佛商学院最受欢迎的领导课》:讲给CEO的管理学常识、常见错误和改进方法
哈佛商学院最受欢迎的领导课 英文版出版于2011年,还不算旧.中信2013年出过一版,这版估计是英文书版权过期后重新购买了再出版. 全书以写给CEO的口吻讲了许多管理常识,包含一些CEO容易犯的问题和 ...
- 记录一下自己申请并使用VPS的全过程
在学习REST API的时候,想要阅读一下谷歌爸爸的api design guide,无奈无情被墙,正好在学习云相关的技术,就想到申请一个VPS来用用. 这次我选择的是hostmybytes,原因有两 ...
- python正则表达式re之compile函数解析
re正则表达式模块还包括一些有用的操作正则表达式的函数.下面主要介绍compile函数. 定义: compile(pattern[,flags] ) 根据包含正则表达式的字符串创建模式对象. 通过py ...
- J2EE,J2SE,J2ME,JDK,SDK,JRE,JVM区别(转载)
转载地址:http://blog.csdn.net/alspwx/article/details/20799017 一.J2EE.J2SE.J2ME区别 J2EE——全称Java 2 Enterpri ...
- NULL指针引起的一个linux内核漏洞
NULL指针一般都是应用于有效性检测的,其实这里面有一个约定俗成的规则,就是说无效指针并不一定是 NULL,只是为了简单起见,规则约定只要指针无效了就将之设置为NULL,结果就是NULL这个指针被用来 ...
- QJsonDocument实现Qt下JSON文档读写
版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QJsonDocument实现Qt下JSON文档读写 本文地址:http://tech ...
- nexus在linux上搭建
Maven 仓库的分类:(maven的仓库只有两大类) 1.本地仓库 2.远程仓库,在远程仓库中又分成了3种: 2.1 中央仓库 2.2 私服 2.3 其它公共库 有个maven私服可以很方便地管理我 ...
- [学习]WireShark 的过滤功能
1. 打开 wireShark 过滤显示 协议 比如显示arp协议 过滤栏输入arp即可 支持的协议类型 TCP UDP HTTP FTP ICMP SMTP等等 2. 过滤ip地址 ip.addr ...
- windows操作系统下载tomcat,并与eclipse进行整合
进入Tomcat官网之后,在左边我们看到,Tomcat的有6,7,8这三个最流行的版本,我们可以点击进去下载想要的版本. 进入里面之后,可以看见有64位的和32位的,就看自己的电脑是多少位的了,如果电 ...
- jenkin报错hudson.plugins.git.GitExcept
清除工作空间 转载请注明博客出处:http://www.cnblogs.com/cjh-notes/