题目大意:给你一个逻辑表达式,然后让你计算表达式为真的取值情况数,表达式由一系列的 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. 青岛Uber优步司机奖励政策(1月4日~1月10日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  2. [数据结构]_[C/C++]_[链表的最佳创建方式]

    场景 1.链表在C/C++里使用非常频繁, 因为它非常使用, 可作为天然的可变数组. push到末尾时对前面的链表项不影响. 反观C数组和std::vector, 一个是静态大小, 一个是增加多了会对 ...

  3. LeetCode:39. Combination Sum(Medium)

    1. 原题链接 https://leetcode.com/problems/combination-sum/description/ 2. 题目要求 给定一个整型数组candidates[ ]和目标值 ...

  4. Python科学计算器(计算器)

    说明 该计算器主要是为了练习正则表达式以及python基础所写:代码比较low! 运行过程 请输入你的计算公式, 计算器会将计算结果输出到屏幕上(此处会打印步骤); 退出(exit/quit) MyC ...

  5. fastDFS 分布式文件系统应用

    环境准备 使用的系统软件 名称 说明 centos 7.x libfatscommon FastDFS分离出的一些公用函数包 FastDFS FastDFS本体 fastdfs-nginx-modul ...

  6. oradebug 的学习 一

        说明 oradebug主要是给oracle支持人员使用的,尽管很早便有,但oracle官网很少有记载.他是个sql*plus命令行工具,有sysdba的权限就可以登入,无需特别设置.他可以被用 ...

  7. JVM监控远程服务器

    1. 首先配置服务器端,进入服务器tomcat的bin目录下,打开catalina.sh配置文件,xxx为服务器配置路径. # cd /xxx/apache-tomcat-/bin # vim cat ...

  8. Linux命令应用大词典-第17章 软件包管理

    17.1 rpm:RPM软件包管理器 17.2 rpmargs:处理RPM软件包 17.3 rpmbuild:构建RPM软件包 17.4 rpmdiff:比较两个软件包之间的不同 17.5 rpmel ...

  9. (转)Shadow Mapping

    原文:丢失,十分抱歉,这篇是在笔记上发现的.SmaEngine 阴影和级联部分是模仿UE的结构设计   This tutorial will cover how to implement shadow ...

  10. Java进阶知识点:不可变对象与并发

    一.String的不可变特性 熟悉Java的朋友都知道,Java中的String有一个很特别的特性,就是你会发现无论你调用String的什么方法,均无法修改this对象的状态.当确实需要修改Strin ...