我的FMT是在VFleaKing的论文中学到的。51Nod的评测机好恶心。

题目分析:

题目很明显是要你求一个类似卷积的式子。但是我们可以注意到前面具有组合数,如果拆成阶乘会很大,在模意义下你无法判断奇偶性。另辟蹊径,可以采用Lucas定理分析。

观察组合数的奇偶性,就会发现$\binom{n}{k} % 2 == 0$的充要条件是在模$2$意义下不存在$\binom{0}{1}$。这意味着$\binom{0}{0} \binom{1}{1} \binom{1}{0}$都是可以接受的。换句话说$k$是$n$的子集。注意到原来的是基础的卷积形式,所以我们要做的是对a和b的子集卷积。

全程在模$2$意义下进行,不难想到用二进制压位。

代码:

 #include<bits/stdc++.h>
using namespace std; #define RI register int const int maxn = (<<)+; int n,m,len;
int a[maxn],b[maxn];
char buffer[], *buf=buffer; inline void in(int &x) {
while(*buf>'' || *buf<'') ++buf;
for(x=;*buf>=''&&*buf<=''; ++buf) x=x*+*buf-'';
} inline void in1(int &x){
while(*buf>'' || *buf<'') ++buf;
x = *buf-'';++buf;
} struct Bitset{
unsigned long long data[<<];
int PrintBit(int now){
int tm = now>>,im = now&;
return (bool)(data[tm]&(1ll<<im));
}
void reset(int start,int len){
int tm = start>>,im = start&;
if(len >= ){
int ww = len>>;
for(RI i=;i<ww;++i)data[tm+ww+i] ^= data[tm+i];
}else{
long long forw = (((1ll<<len)-)<<im);
forw = (forw&data[tm]);
forw <<= len; data[tm] ^= forw;
}
}
void SetBit(int now){
int tm = now>>,im = now&;
data[tm] |= (1ll<<im);
}
}am[],bm[],cm[]; int cnt[maxn];
int f1,f2; void read(){
in(n),in(m);
for(RI i=;i<=n;++i) in1(a[i]);
for(RI i=;i<=m;++i) in1(b[i]);
for(RI i=;i<=n;++i) a[i] &= ;
for(RI i=;i<=m;++i) b[i] &= ;
n = (n>m?n:m);m = ;len = ;
while(m <= n) m<<=,len++;
a[] = b[] = ;
} void FMT(int place,int st){
if(place == ){
for(RI i=;i<m;i<<=){
int jg = m/(i<<);
for(RI j=;j<m;j+=(jg<<))
am[st].reset(j,jg);
}
}else{
for(RI i=;i<m;i<<=){
int jg = m/(i<<);
for(RI j=;j<m;j+=(jg<<))
bm[st].reset(j,jg);
}
}
} void IFMT(int num){
for(RI i=;i<m;i<<=){
for(RI j=;j<m;j+=(i<<))
cm[num].reset(j,i);
}
} void work(){
for(RI i=;i<m;++i) { cnt[i] = cnt[i>>]+(i&); }
for(RI i=;i<=n;++i) {
if(a[i]) am[cnt[i]].SetBit(i);
if(b[i]) bm[cnt[i]].SetBit(i);
}
for(RI i=;i<=len;++i){ FMT(,i); FMT(,i); }
for(RI i=;i<m;++i){
f1 = ,f2 = ;
for(RI j=;j<=len;++j){
f1 += (am[j].PrintBit(i)<<j);
f2 += (bm[j].PrintBit(i)<<j);
}
int n1 = ,n2 = ;
for(RI j=;j<=len;++j){
n1 = n1+(f1&(<<j));
if(f2&(<<j)) n2 = (n2<<)+;
else n2 <<=;
if(cnt[n1&n2]&) cm[j].SetBit(i);
}
}
for(RI i=;i<=len;++i) IFMT(i);
long long ans = ;
for(RI i=;i<m;++i){
ans += 1ll*cm[cnt[i]].PrintBit(i)*i*i;
}
printf("%lld",ans);
} int main(){
fread(buffer, , (sizeof buffer)-, stdin);
read();
work();
return ;
}

51Nod1824 染色游戏 【Lucas定理】【FMT】【位运算】的更多相关文章

  1. LeetCode | 289. 生命游戏(原地算法/位运算)

    记录dalao的位运算骚操作 根据百度百科 ,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在 1970 年发明的细胞自动机. 给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细 ...

  2. BZOJ 1647 [Usaco2007 Open]Fliptile 翻格子游戏:部分枚举 位运算

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1647 题意: 在一个n*m(1 <= n,m <= 15)的棋盘上,每一个格子 ...

  3. 【算法学习笔记】组合数与 Lucas 定理

    卢卡斯定理是一个与组合数有关的数论定理,在算法竞赛中用于求组合数对某质数的模. 第一部分是博主的个人理解,第二部分为 Pecco 学长的介绍 第一部分 一般情况下,我们计算大组合数取模问题是用递推公式 ...

  4. 【2018寒假集训 Day1】【位运算】翻转游戏

    翻转游戏(flip) [问题描述] 翻转游戏是在一个 4 格×4 格的长方形上进行的,在长方形的 16 个格上每 个格子都放着一个双面的物件.每个物件的两个面,一面是白色,另一面是黑色, 每个物件要么 ...

  5. @总结 - 2@ 位运算卷积/子集卷积 —— FWT/FMT

    目录 @0 - 参考资料@ @1 - 异或卷积概念及性质@ @2 - 快速沃尔什正变换(异或)@ @3 - 快速沃尔什逆变换(异或)@ @4 - 与卷积.或卷积@ @5 - 参考代码实现@ @6 - ...

  6. 51Nod 1069 Nim游戏 (位运算)

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1069 有N堆石子.A B两个人轮流拿,A先拿.每次只能从一堆 ...

  7. 【洛谷4424】[HNOI/AHOI2018] 寻宝游戏(位运算思维题)

    点此看题面 大致题意: 给你\(n\)个\(m\)位二进制数.每组询问给你一个\(m\)位二进制数,要求你从\(0\)开始,依次对于这\(n\)个数进行\(and\)或\(or\)操作,问有多少种方案 ...

  8. 组合数取模Lucas定理及快速幂取模

    组合数取模就是求的值,根据,和的取值范围不同,采取的方法也不一样. 下面,我们来看常见的两种取值情况(m.n在64位整数型范围内) (1)  , 此时较简单,在O(n2)可承受的情况下组合数的计算可以 ...

  9. Lucas定理及应用

    额,前两天刚讲了数据结构,今天我来讲讲组合数学中的一种奇妙优化——Lucas 先看这样一个东西 没学过lucas的肯定会说:还不简单?处理逆元,边乘边膜呗 是,可以,但注意一下数据范围 你算这一次,你 ...

随机推荐

  1. Ordering Tasks

    链接 [https://vjudge.net/contest/281085#problem/D] 题意 有n个任务,有M个对先后顺序 然你输出最后的完成任务的顺序,有多种可能输出一种即可 分析 裸的拓 ...

  2. 把玩Alpine linux(二):APK包管理器

    导读 Alpine Linux非常精简,开机内存占用也在二三十兆大,没有拆箱即用,就需要我们自己去做一些了解和配置 Alpine Linux的优劣 优势 Alpine Linux的Docker镜像特点 ...

  3. Django ORM 反向查询

    一/一对多反向查询   先定义两个模型,一个是A,一个是B,是一对多的类型. class A(models.Model): name= models.CharField('名称', max_lengt ...

  4. Git更新代码到本地

    一段时间没用git,发现一些东西记不住了,这里记一点常用的命令. 正规流程 git status(查看本地分支文件信息,确保更新时不产生冲突) 若出现冲突,会有提示的 git checkout – [ ...

  5. mysql_单表查询

    单表查询 比较符 当在子句中使用 <. >. <=. >=. <>或 !=时,字段的名字不加引号.如果使用引号,则查询出的结果为空,并且不会报错. ; 等号 当在子 ...

  6. echarts使用笔记二:柱子堆叠

    1.多个柱子堆叠效果,多用于各部分占比 app.title = '坐标轴刻度与标签对齐'; option = { title : { //标题 x : 'center', y : 5, text : ...

  7. #Leetcode# 989. Add to Array-Form of Integer

    https://leetcode.com/problems/add-to-array-form-of-integer/ For a non-negative integer X, the array- ...

  8. 【Python3练习题 002】企业发放的奖金根据利润提成

    # [Python练习题 002]企业发放的奖金根据利润提成.# 利润(I)低于或等于10万元时,奖金可提10%:利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分, ...

  9. Angular 自定义指令传参

    <!DOCTYPE html><html ng-app="myApp"><head lang="en"> <meta ...

  10. C# Note5:使用相对路径读取文件

    一.C#中使用相对路径读取配置文件 一般Solution的目录结构如下图所示: (如过看不到某些文件,可以点击 “显示所有文件” 图标) 方法一:由于生成的exe文件在bin\debug目录下,可以使 ...