题目大意:给你一个逻辑表达式,然后让你计算表达式为真的取值情况数,表达式由一系列的 a 或者 a|b 亦或起来,每个变量最多出现两次(包括反变量)

嘴炮开始:每个变量最多出现两次,那么跟它相关联的变量也最多是两个,转化成图的话,那么整个图就是由很多链和很多环组成,分别DP就好了;

链DP很简单,从一段DP到另一端就可以了

环上的DP就是先确定一个点的值然后链DP就好了,一个环DP两次

写起来感觉还是有点麻烦。。

#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std; const int mod=1e9+;
const int maxn=*;
int n,m,d[maxn];
int fir[maxn],last[maxn<<],nex[maxn<<],a[maxn<<],b[maxn<<],tot=;
vector <int> e[maxn];
bool vis[maxn];
long long dp[maxn][][]; int sgn(int x)
{
if(x>)return ;
if(x<)return ;
} void add(int u,int v,int aa,int bb)
{
++tot;
last[tot]=v;
a[tot]=aa;
b[tot]=bb;
nex[tot]=fir[u];
fir[u]=tot;
} struct node{
int a,b;
}fa[maxn];
bool evis[maxn<<];
int s[maxn],cnt; void dfs(int x)
{
//printf("%d\n",x);
vis[x]=;
s[++cnt]=x;
for(int i = fir[x];i;i=nex[i])
{
if(!evis[i])
{
evis[i]=;
evis[i^]=;
fa[x]=(node){a[i],b[i]};
if(!vis[last[i]])dfs(last[i]);
}
}
} void up(long long &a,long long b)
{
a+=b;
a%=mod;
} int main()
{
scanf("%d%d",&n,&m);
long long ans1=,ans0=;
for(int i = ;i <= n;i++)
{
int k;
scanf("%d",&k);
if(k==)
{
int x;
scanf("%d",&x);
e[abs(x)].push_back(sgn(x));
}
else
{
int u,v;
scanf("%d%d",&u,&v);
if(abs(u)==abs(v))
{
if(u!=v)
{
vis[abs(u)]=;
swap(ans1,ans0);
ans1=ans1*%mod;
ans0=ans0*%mod;
}
else
{
e[abs(u)].push_back(sgn(u));
}
continue;
}
add(abs(u),abs(v),sgn(u),sgn(v));
add(abs(v),abs(u),sgn(v),sgn(u));
d[abs(u)]++;
d[abs(v)]++;
}
}
for(int i = ;i <= m;i++)
if(!vis[i] && d[i]== && e[i].size()>)
{
vis[i]=;
if(e[i].size()==)
{
ans1=(ans1+ans0)%mod;
ans0=ans1;
}
else
{
if(e[i][]==e[i][])
{
ans1=ans1*%mod;
ans0=ans0*%mod;
}
else
{
swap(ans1,ans0);
ans1=ans1*%mod;
ans0=ans0*%mod;
}
}
//printf("%I64d %I64d\n",ans1,ans0);
}
for(int i = ;i <= m;i++)
if(d[i]== && !vis[i])
{
cnt=;
dfs(i);
dp[i][][]=;
dp[i][][]=;
dp[i][][]=;
dp[i][][]=;
if(e[i].size())
{
if(e[i][]==)
{
swap(dp[i][][],dp[i][][]);
}
else
{
swap(dp[i][][],dp[i][][]);
}
}
for(int step = ;step < cnt;step++)
{
for(int ii = ;ii < ;ii++)
for(int jj = ;jj < ;jj++)
for(int kk = ;kk < ;kk++)
{
up(dp[s[step+]][kk][((ii^fa[s[step]].a)|(kk^fa[s[step]].b))^jj],dp[s[step]][ii][jj]);
}
}
int x=s[cnt];
if(e[x].size())
{
if(e[x][]==)
{
swap(dp[x][][],dp[x][][]);
}
else
{
swap(dp[x][][],dp[x][][]);
}
}
//printf("xx %I64d %I64d %I64d %I64d\n",dp[x][0][0],dp[x][0][1],dp[x][1][0],dp[x][1][1]);
long long a1=,a0=; //printf("%I64d %I64d\n",ans1,ans0);
a1=(dp[x][][]+dp[x][][])*ans1%mod+(dp[x][][]+dp[x][][])*ans0%mod;
a0=(dp[x][][]+dp[x][][])*ans0%mod+(dp[x][][]+dp[x][][])*ans1%mod;
ans1=a1%mod;
ans0=a0%mod;
//printf("%I64d %I64d\n",ans1,ans0);
}
for(int i = ;i <= m;i++)
if(d[i]== && !vis[i])
{
cnt=;
dfs(i);
dp[i][][]=;
dp[i][][]=;
dp[i][][]=;
dp[i][][]=;
for(int step = ;step <= cnt;step++)
memset(dp[s[step]],,sizeof(dp[s[step]]));
for(int step = ;step < cnt;step++)
{
for(int ii = ;ii < ;ii++)
for(int jj = ;jj < ;jj++)
for(int kk = ;kk < ;kk++)
{
up(dp[s[step+]][kk][((ii^fa[s[step]].a)|(kk^fa[s[step]].b))^jj],dp[s[step]][ii][jj]);
}
}
int x=s[cnt];
for(int ii=;ii<;ii++)
if((ii^fa[x].a)|(fa[x].b))swap(dp[x][ii][],dp[x][ii][]);
long long a1=,a0=;
//printf("xx %I64d %I64d %I64d %I64d\n",dp[x][0][0],dp[x][0][1],dp[x][1][0],dp[x][1][1]);
a1+=(dp[x][][]+dp[x][][])*ans1%mod+(dp[x][][]+dp[x][][])*ans0%mod;
a0+=(dp[x][][]+dp[x][][])*ans0%mod+(dp[x][][]+dp[x][][])*ans1%mod; dp[i][][]=;
dp[i][][]=;
dp[i][][]=;
dp[i][][]=;
for(int step = ;step <= cnt;step++)
memset(dp[s[step]],,sizeof(dp[s[step]]));
for(int step = ;step < cnt;step++)
{
for(int ii = ;ii < ;ii++)
for(int jj = ;jj < ;jj++)
for(int kk = ;kk < ;kk++)
{
up(dp[s[step+]][kk][((ii^fa[s[step]].a)|(kk^fa[s[step]].b))^jj],dp[s[step]][ii][jj]);
}
}
for(int ii=;ii<;ii++)
if((ii^fa[x].a)|(^fa[x].b))swap(dp[x][ii][],dp[x][ii][]);
//printf("xx %I64d %I64d %I64d %I64d\n",dp[x][0][0],dp[x][0][1],dp[x][1][0],dp[x][1][1]);
a1+=(dp[x][][]+dp[x][][])*ans1%mod+(dp[x][][]+dp[x][][])*ans0%mod;
a0+=(dp[x][][]+dp[x][][])*ans0%mod+(dp[x][][]+dp[x][][])*ans1%mod;
ans1=a1%mod;
ans0=a0%mod;
//printf("%I64d %I64d\n",ans1,ans0);
}
for(int i = ;i <= m;i++)
if(!vis[i])ans1=ans1*%mod;
printf("%I64d\n",ans1);
return ;
}

AC code

CodeForces - 704C的更多相关文章

  1. Codeforces 704C - Black Widow(dp)

    Codeforces 题目传送门 & 洛谷题目传送门 u1s1 感觉这种题被评到 *2900 是因为细节太繁琐了,而不是题目本身的难度,所以我切掉这种题根本不能说明什么-- 首先题目中有一个非 ...

  2. Black Widow CodeForces - 704C (dp)

    大意: 给定一个m个bool变量的方程, 求方程解的个数 给定方程的形式类似于这样 每个括号是一个子式, 每个子式里变量数不超过2, 每个变量出现次数不超过2, 方程右侧一直是1 对每个变量出现的式子 ...

  3. python爬虫学习(5) —— 扒一下codeforces题面

    上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...

  4. 【Codeforces 738D】Sea Battle(贪心)

    http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...

  5. 【Codeforces 738C】Road to Cinema

    http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...

  6. 【Codeforces 738A】Interview with Oleg

    http://codeforces.com/contest/738/problem/A Polycarp has interviewed Oleg and has written the interv ...

  7. CodeForces - 662A Gambling Nim

    http://codeforces.com/problemset/problem/662/A 题目大意: 给定n(n <= 500000)张卡片,每张卡片的两个面都写有数字,每个面都有0.5的概 ...

  8. CodeForces - 274B Zero Tree

    http://codeforces.com/problemset/problem/274/B 题目大意: 给定你一颗树,每个点上有权值. 现在你每次取出这颗树的一颗子树(即点集和边集均是原图的子集的连 ...

  9. CodeForces - 261B Maxim and Restaurant

    http://codeforces.com/problemset/problem/261/B 题目大意:给定n个数a1-an(n<=50,ai<=50),随机打乱后,记Si=a1+a2+a ...

随机推荐

  1. SpringBoot-04:SpringBoot在idea中的俩种创建方式

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 创建SpringBoot工程有很多种方式,我只讲俩种最为常见的 一,依托springboot官网提供的模板.( ...

  2. 基于Kafka的服务端用户行为日志采集

    本文来自网易云社区 作者:李勇 背景 随着互联网的不断发展,用户所产生的行为数据被越来越多的网站重视,那么什么是用户行为呢?所谓的用户行为主要由五种元素组成:时间.地点.人物.行为.行为对应的内容.为 ...

  3. 角色 RESOURCE、CONNECT、DBA具有的权限

    角色 RESOURCE.CONNECT.DBA具有的权限 select grantee,privilege from dba_sys_privs where grantee='RESOURCE' or ...

  4. 一次IPC无法创建的问题

    背景说明:         后台子系统都是运行在pc上的linux         系统有多个子系统,有一个子系统负责统一启停其他子系统,这里把这个子系统称为olddriver.         ol ...

  5. focus如何实现事件委托

    事件委托是利用事件冒泡机制的一种优化手段,如果有很多列表元素要绑定事件,那么就可以用事件委托来优化(不需要给每个元素都绑定事件).但是对于focus这种特殊的表单事件,它不会冒泡,那么又该如何实现这一 ...

  6. 安装MySQLdb模块遭遇"fatal error: my_config.h: No such file or directory"的处理

    Issue       I encountered an error when I run the python script which need to import the module of & ...

  7. Web自动化selenium技术快速实现爬虫

    selenium是大家众所周知的web自动化测试框架,主要用来完成web网站项目的自动化测试,但其实如果要实现一个web爬虫,去某些网站爬取数据,其实用selenium来实现也很方便. 比如,我们现在 ...

  8. GIt学习第一天之安装和版本库创建

    搬运自 ‘廖雪峰的官方网站’ 1.git安装 官网下载地址:https://git-scm.com/download/win   百度网盘下载地址:https://pan.baidu.com/s/1k ...

  9. flume 整合 kafka

    flume 整合 kafka:   flume:高可用的,高可靠的,分布式的海量日志采集.聚合和传输的系统. kafka:分布式的流数据平台.   flume 采集业务日志,发送到kafka   一. ...

  10. Linux 文件的常识

    文件 文件的分类 文件 目录 链接 区分办法,ls -la 查看 十个标志符中的第一个 如:drwxrwxr-x. 2 normal normal 4096 8月 31 23:43 dir 目录是d ...