【CodeForces】704 C. Black Widow 动态规划+模拟
【题目】C. Black Widow
【题意】给定一个表达式,形式为(...)^(...)^......^(...)=1(n个括号),括号中为1~2个值取或。有m个变量,给出表达式的值为xi或 !xi,xi只能为0或1,求变量赋值使得表达式成立的方案数。每个变量至多出现两次。n,m<=10^5。
【算法】动态规划+模拟
【题解】每个括号视为一个点,对于同时出现在两个括号内的变量将两个点连边(边须记两边异同)。由于每个变量至多出现两次,所以一条边就可以代表一个变量。
由于每个括号至多两个变量,所以整个图是若干独立的链或环。
对于链:f[i][j][k]表示考虑到第i条边,当前边取值j=0或1,当前全局取值k=0或1的方案数。
从链的一端开始考虑,到链的另一端结束。
对于环:先决定好第一条边的取值,然后像链一样做即可。
最后将若干子图用简单的DP或组合数计算出最终答案。
复杂度O(n)。
实际操作过程相当复杂,请务必小心食用本题……QAQ
#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
using namespace std;
int read(){
char c;int s=,t=;
while(!isdigit(c=getchar()))if(c=='-')t=-;
do{s=s*+c-'';}while(isdigit(c=getchar()));
return s*t;
}
const int maxn=,MOD=1e9+;
int f[maxn][][],dp[][],tot=,first[maxn],in[maxn],ans[maxn][],cnt,fir;
int n,m,c[maxn][],d[maxn][],uv,uuv,vv,be,fr,p[maxn];
bool vis[maxn];
struct edge{int v,w,from;}e[maxn*];
void insert(int u,int v,int w){tot++;e[tot].v=v;e[tot].w=w;e[tot].from=first[u];first[u]=tot;in[v]++;}
int M(int x){return x>=MOD?x-MOD:x;}
void dfs(int x,int fa,int w){
bool ok=;vis[x]=;
f[x][][]=M(f[fa][][w]+f[fa][][w^]);
f[x][][]=M(f[fa][][]+f[fa][][]);
f[x][][]=M(f[fa][][w^]+f[fa][][w]);
f[x][][]=M(f[fa][][]+f[fa][][]);
for(int i=first[x];i;i=e[i].from)if(e[i].v!=fa){
ok=;
dfs(e[i].v,x,e[i].w);
}
if(ok){ ans[cnt][]=M(ans[cnt][]+M(f[x][][]+(p[x]?:f[x][][])));
ans[cnt][]=M(ans[cnt][]+M(f[x][][]+(p[x]?:f[x][][])));
}
}
void round(int x,int fa,int w,int b){
vis[x]=;
f[x][][]=M(f[fa][][w]+f[fa][][w^]);
f[x][][]=M(f[fa][][]+f[fa][][]);
f[x][][]=M(f[fa][][w^]+f[fa][][w]);
f[x][][]=M(f[fa][][]+f[fa][][]);
for(int i=first[x];i;i=e[i].from)if(i!=fr&&(i^)!=b){
if(e[i].v!=be)round(e[i].v,x,e[i].w,i);
else{
if(!fir){
ans[cnt][]=M(f[x][e[i].w^][]+f[x][e[i].w][]);
ans[cnt][]=M(f[x][e[i].w][]+f[x][e[i].w^][]);
}
else{
ans[cnt][]=M(ans[cnt][]+M(f[x][][]+f[x][][]));
ans[cnt][]=M(ans[cnt][]+M(f[x][][]+f[x][][]));
}
}
}
}
int main(){
n=read();m=read();
for(int i=;i<=n;i++){
int k=read();if(k==)p[i]=;
for(int j=;j<=k;j++){
int x=read();
if(x<)c[-x][++c[-x][]]=i,d[-x][c[-x][]]=;
else c[x][++c[x][]]=i;
}
}
for(int i=;i<=m;i++){
if(c[i][]==)uv++;
if(c[i][]==){
if(c[i][]==c[i][]){p[c[i][]]=;if(d[i][]==d[i][])uuv++;else vv++;continue;}
insert(c[i][],c[i][],d[i][]^d[i][]);
insert(c[i][],c[i][],d[i][]^d[i][]);
}
}
for(int i=;i<=n;i++)if(!vis[i]&&in[i]==){
cnt++;
f[][][]=;
dfs(i,,);
if(!p[i]){
dfs(i,,);
}
f[][][]=;
}
for(int i=;i<=n;i++)if(!vis[i]&&in[i]==){
cnt++;
f[i][][]=;fir=;be=i;vis[i]=;fr=e[first[i]].from;
round(e[first[i]].v,i,e[first[i]].w,first[i]);
f[i][][]=;f[i][][]=;fir=;
round(e[first[i]].v,i,e[first[i]].w,first[i]);
}
for(int i=;i<=n;i++)if(!vis[i]&&in[i]==&&p[i]!=){cnt++;ans[cnt][]=;ans[cnt][]=p[i]?:;}
int x=;
dp[x][vv&]=;
for(int i=;i<=vv;i++)dp[x][vv&]=dp[x][vv&]*%MOD;
for(int i=;i<=uuv;i++){
x=-x;
dp[x][]=M(dp[-x][]+dp[-x][]);
dp[x][]=M(dp[-x][]+dp[-x][]);
}
for(int i=;i<=cnt;i++){
x=-x;
dp[x][]=(1ll*ans[i][]*dp[-x][]+1ll*ans[i][]*dp[-x][])%MOD;
dp[x][]=(1ll*ans[i][]*dp[-x][]+1ll*ans[i][]*dp[-x][])%MOD;
}
for(int i=;i<=uv;i++)dp[x][]=dp[x][]*%MOD;
printf("%d",dp[x][]);
return ;
}
【CodeForces】704 C. Black Widow 动态规划+模拟的更多相关文章
- codeforces 723B Text Document Analysis(字符串模拟,)
题目链接:http://codeforces.com/problemset/problem/723/B 题目大意: 输入n,给出n个字符的字符串,字符串由 英文字母(大小写都包括). 下划线'_' . ...
- Codeforces Round #304 C(Div. 2)(模拟)
题目链接: http://codeforces.com/problemset/problem/546/C 题意: 总共有n张牌,1手中有k1张分别为:x1, x2, x3, ..xk1,2手中有k2张 ...
- Codeforces 749C:Voting(暴力模拟)
http://codeforces.com/problemset/problem/749/C 题意:有n个人投票,分为 D 和 R 两派,从1~n的顺序投票,轮到某人投票的时候,他可以将对方的一个人K ...
- Educational Codeforces Round 2 A. Extract Numbers 模拟题
A. Extract Numbers Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/600/pr ...
- Codeforces 716B Complete the Word【模拟】 (Codeforces Round #372 (Div. 2))
B. Complete the Word time limit per test 2 seconds memory limit per test 256 megabytes input standar ...
- CodeForces 797C Minimal string:贪心+模拟
题目链接:http://codeforces.com/problemset/problem/797/C 题意: 给你一个非空字符串s,空字符串t和u.有两种操作:(1)把s的首字符取出并添加到t的末尾 ...
- Codeforces 37D Lesson Timetable - 组合数学 - 动态规划
题目传送门 神奇的门I 神奇的门II 题目大意 有$n$组学生要上课2次课,有$m$个教室,编号为$1$到$m$.要确定有多少种不同的安排上课的教室的方案(每组学生都是本质不同的),使得它们满足: 每 ...
- Codeforces Beta Round #3 C. Tic-tac-toe 模拟题
C. Tic-tac-toe 题目连接: http://www.codeforces.com/contest/3/problem/C Description Certainly, everyone i ...
- Codeforces Beta Round #1 B. Spreadsheets 模拟
B. Spreadsheets 题目连接: http://www.codeforces.com/contest/1/problem/B Description In the popular sprea ...
随机推荐
- 使用coding.net上传项目
鉴于上一次上传托管代码的惨烈教训,痛定思痛,决定把这次使用cooding.net上传的过程记录下来.也算是一篇简单的cooding初级使用教程了. 1.首先在cooding上新建项目 (1)填写项目名 ...
- 【beta】Scrum站立会议第3次....11.6
小组名称:nice! 组长:李权 成员:于淼 刘芳芳韩媛媛 宫丽君 项目内容:约跑app(约吧) 时间:2016.11.6 12:00——12:30 地点:传媒西楼220室 本次对beta阶段的需 ...
- webgl 深度缓冲
传统的画2d画布就是后画的会盖在先画的上面,但是在画一些三维图形时,这很难控制 深度缓冲区的作用就是区分颜色所在的层次,防止把被遮挡住的颜色显示出来. 深度缓冲很强大,用起来很简单 开启深度缓冲(测试 ...
- Web模块:spring-boot-starter-web
spring-boot-autoconfigure-1.5.1.RELEASE.jar!/org/springframework/boot/autoconfigure/web 上述jar的web包下, ...
- EM算法[转]
最大期望算法:EM算法. 在统计计算中,最大期望算法(EM)是在概率模型中寻找参数最大似然估计或者最大后验估计的算法,其中概率模型依赖于无法观测的隐藏变量. 最大期望算法经过两个步骤交替进行计算: 第 ...
- python的N个小功能之正则匹配
1.. 匹配任意除换行符“\n”外的字符:2.*表示匹配前一个字符0次或无限次:3.+或*后跟?表示非贪婪匹配,即尽可能少的匹配,如*?重复任意次,但尽可能少重复,惰性匹配:4. .*? 表示匹配任意 ...
- poj2914-Minimum Cut
题意 \(n\) 个点 \(m\) 条边的无向带权图求全局最小割.\(n\le 500,m\le \frac{n(n-1)}{2}\) . 分析 参考了 这篇博客,去给他点赞. 嘛,今天研究了一下全局 ...
- Liunx 和 Win中的软链接详解
用过Linux的朋友都知道linux中有软链接的概念,可以通过ln命令创建到目录或文件的软链接,软链接的好处就是可以让一个目录或文件有多个入口但保持单一物理位置,方便应用和管理. 1.命令格式: ...
- (转)Linux GCC常用命令
1简介 2简单编译 2.1预处理 2.2编译为汇编代码(Compilation) 2.3汇编(Assembly) 2.4连接(Linking) 3多个程序文件的编译 4检错 5库文件连接 5.1编译成 ...
- 【刷题】BZOJ 3365 [Usaco2004 Feb]Distance Statistics 路程统计
Description 在得知了自己农场的完整地图后(地图形式如前三题所述),约翰又有了新的问题.他提供 一个整数K(1≤K≤109),希望你输出有多少对农场之间的距离是不超过K的. Input 第1 ...