【题解】毒蛇越狱(FWT+容斥)
【题解】毒蛇越狱(FWT+容斥)
问了一下大家咋做也没听懂,按兵不动没去看题解,虽然已经晓得复杂度了....最后感觉也不难
用FWT_OR和FWT_AND做一半分别求出超集和和子集和,然后
- 枚举问号是01,裸的,\(O(2^{cnt[?]})\)
- 默认问号是1,利用子集和求,\(O(2^{cnt[1]})\)
- 默认问号是0,利用超集和求,\(O(2^{cnt[0]})\)
可以知道\(min(cnt)\le n/3\),所以复杂度\(O(n2^n 2^{n/3}Q)\)
//@winlere
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; typedef long long ll;
inline int qr(){
int ret=0,f=0,c=getchar();
while(!isdigit(c)) f|=c==45,c=getchar();
while( isdigit(c)) ret=ret*10+c-48,c=getchar();
return f?-ret:ret;
}
const int maxn=1<<20|1;
char s[maxn];
int data[maxn],c[maxn],s0[maxn],s1[maxn],n,q;
int cnt[3];
inline void FWT_AND(int*a,const int&len,const int&tag){
for(int t=1;t<len;t<<=1)
for(int i=0;i<len;i+=t<<1)
for(int k=0;k<t;++k)
a[i+k]+=a[t+i+k]*tag;
}
inline void FWT_OR(int*a,const int&len,const int&tag){
for(int t=1;t<len;t<<=1)
for(int i=0;i<len;i+=t<<1)
for(int k=0;k<t;++k)
a[t+i+k]+=a[i+k]*tag;
}
int num[maxn],u;
int main(){
n=qr(); q=qr();
u=(1<<n)-1;
scanf("%s",s);
for(int t=1;t<1<<n;++t) num[t]=num[t^(t&-t)]+1;
for(int t=0;t<1<<n;++t) data[t]=s[t]-48,s0[t]=data[t],s1[t]=data[t];
FWT_AND(s0,1<<n,1); FWT_OR(s1,1<<n,1);
while(q--){
if(scanf("%s",s)==EOF) return 0;
memset(cnt,0,sizeof cnt);
for(int t=0;t<n;++t){
if(isdigit(s[t])) c[t]=s[t]==49;
else c[t]=2;
++cnt[c[t]];
}
int base=0,wen=0,ans=0,k=min({cnt[0],cnt[1],cnt[2]});
for(int t=0;t<n;++t)
if(c[t]<=1) base=base<<1|c[t],wen<<=1;
else wen=wen<<1|1,base<<=1;
if(cnt[2]==k){
for(int t=wen;~t;--t>=0?t&=wen:t)
ans+=data[t|base];
}else if(cnt[1]==k){
for(int t=base;~t;--t>=0?t&=base:t){
int g=t|wen;
if(num[base^t]&1) ans-=s1[g];
else ans+=s1[g];
}
}else{
base^=u; base^=wen;
for(int t=base;~t;--t>=0?t&=base:t){
int g=t|wen;
if(num[base^t]&1) ans-=s0[g^u];
else ans+=s0[g^u];
}
}
printf("%d\n",ans);
}
return 0;
}
【题解】毒蛇越狱(FWT+容斥)的更多相关文章
- 【题解】Counting D-sets(容斥+欧拉定理)
[题解]Counting D-sets(容斥+欧拉定理) 没时间写先咕咕咕. vjCodeChef - CNTDSETS 就是容斥,只是难了一二三四五\(\dots \inf\)点 题目大意: 给定你 ...
- BZOJ 1008--[HNOI2008]越狱(容斥&快速幂)
1008: [HNOI2008]越狱 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 12593 Solved: 5439[Submit][Status ...
- CF 449D 题解(状压+容斥)
状压妙啊... 本题的主体思路:状压+容斥原理(或状压+数位dp) 记g[i]表示按位与后结果所有位上至少有i个1的方案数 那么根据容斥原理,ans=g[0]-g[1]+g[2]-g[3]+g[4]. ...
- How Many Sets I(容斥定理)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3556 How Many Sets I Time Limit: 2 ...
- kth min_max容斥
题解: 普通的$min-max$容斥是用来求最后出现元素的期望之类的 $kth min-max$容斥进一步解决倒数第k个出现的元素的期望 给出公式: $kthmax(S)=\sum\limits_{T ...
- 【CF900D】Unusual Sequences 容斥(莫比乌斯反演)
[CF900D]Unusual Sequences 题意:定义正整数序列$a_1,a_2...a_n$是合法的,当且仅当$gcd(a_1,a_2...a_n)=x$且$a_1+a_2+...+a_n= ...
- 【BZOJ2839】集合计数(容斥,动态规划)
[BZOJ2839]集合计数(容斥,动态规划) 题面 BZOJ 权限题 Description 一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使 ...
- 【BZOJ4596】黑暗前的幻想乡(矩阵树定理,容斥)
[BZOJ4596]黑暗前的幻想乡(矩阵树定理,容斥) 题面 BZOJ 有\(n\)个点,要求连出一棵生成树, 指定了一些边可以染成某种颜色,一共\(n-1\)种颜色, 求所有颜色都出现过的生成树方案 ...
- loj2542 「PKUWC2018」随机游走 MinMax 容斥+树上高斯消元+状压 DP
题目传送门 https://loj.ac/problem/2542 题解 肯定一眼 MinMax 容斥吧. 然后问题就转化为,给定一个集合 \(S\),问期望情况下多少步可以走到 \(S\) 中的点. ...
随机推荐
- @codeforces - 1217F@ Forced Online Queries Problem
目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个 n 个点的无向图,标号从 1 到 n.一开始没有任何边 ...
- Hbase架构与实现
- 06多次查询某区间内topk问题
题目描述:给定一个数组,需要多次查找不同区间内的,第k大或者第k小的元素. 考虑题目是多次查找,如果采用只对查询区间内的元素进行排序的思路,然后输出第k大的数的策略,那 ...
- 【HAOI2015】树上染色
[HAOI2015]树上染色 这题思路好神仙啊,首先显然是树形dp,f[i][j]表示在以i为根的子树中选j个黑点对答案的贡献(并不是当前子树最大值),dp时只考虑i与儿子连边的贡献.此时(i,son ...
- Simpson公式的应用(HDU 1724/ HDU 1071)
辛普森积分法 - 维基百科,自由的百科全书 Simpson's rule - Wikipedia, the free encyclopedia 利用这个公式,用二分的方法来计算积分. 1071 ( T ...
- laravel 5.6 请教邮件中的cc,bcc是什么意思,有什么用?
cc指抄送 bcc指暗送. cc:carbon copy bcc:blind carbon copy
- 原生js实现多个随机大小颜色位置速度小球的碰壁反弹
文章地址 https://www.cnblogs.com/sandraryan/ 需求:生成n个小球,让他们在一个大盒子中碰壁反弹,要求小球随机颜色,大小,初始位置,运动速度. 思路分析: 创建小球随 ...
- NLP进阶之(七)膨胀卷积神经网络
NLP进阶之(七)膨胀卷积神经网络1. Dilated Convolutions 膨胀卷积神经网络1.2 动态理解1.2.2 转置卷积动画1.2.3 理解2. Dilated Convolutions ...
- P1057 迷宫路径
题目描述 定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, ...
- H3C 根据子网掩码计算子网数