\(\text{Problem}\)

小H是个善于思考的学生,她正在思考一个有关序列的问题。

她的面前浮现出了一个长度为 \(n\) 的序列 \({ai}\),她想找出两个非空的集合 \(S、T\)。

这两个集合要满足以下的条件:

两个集合中的元素都为整数,且都在 \([1, n]\) 里,即 \(Si,Ti ∈ [1, n]\)。

对于集合 \(S\) 中任意一个元素 \(x\),集合 \(T\) 中任意一个元素 \(y\),满足 \(x < y\)。

对于大小分别为 \(p, q\) 的集合 \(S\) 与 \(T\),满足 \(\text{a[s1] xor a[s2] xor a[s3] ... xor a[sp] = a[t1] and a[t2] and a[t3] ... and a[tq]}\).

小H想知道一共有多少对这样的集合 \((S,T)\),你能帮助她吗?

\(\text{Solution}\)

显然 \(dp\)

一般想到的是 \(f_{i,j}\) 表示顺着做到 \(i\) 位异或值为 \(j\) 的方案数,\(g_{i,j}\) 则是倒着 \(and\) 的方案数

那么枚举临界点计算即可

但是由于正解要压位高精,占据空间,是得分着做很悬

于是考虑一个神奇的 \(dp\)

注意它的 \(j\) 表示倒着做 \(and\) 完后继续那这个值 \(xor\) 后的 \(j\)

所以答案是 \(f[p][0][2]\)

\(p\) 表示使用滚动数组最后得到的状态

转移只要考虑当前位选不选即可

\(\text{Code}\)

#include<cstdio>
#include<iostream>
using namespace std; const int N = 1005, P = 1e8;
int n, a[N]; struct node{
int m[40] = {};
}f[2][1024][3]; inline node operator + (node a, node b)
{
node c;
c.m[0] = max(a.m[0], b.m[0]);
for(int i = 1; i <= c.m[0]; i++)
{
c.m[i] += a.m[i] + b.m[i];
c.m[i + 1] += c.m[i] / P, c.m[i] %= P;
}
if (c.m[c.m[0] + 1] > 0) ++c.m[0];
return c;
} int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
f[0][1023][0].m[0] = f[0][1023][0].m[1] = 1;
int p = 0;
for(int i = n; i; i--)
{
for(int j = 0; j < 1024; j++) f[p ^ 1][j][0] = f[p][j][0], f[p ^ 1][j][1] = f[p][j][1],
f[p ^ 1][j][2] = f[p][j][2];
for(int j = 0; j < 1024; j++)
{
f[p ^ 1][j & a[i]][1] = f[p ^ 1][j & a[i]][1] + f[p][j][0] + f[p][j][1];
f[p ^ 1][j ^ a[i]][2] = f[p ^ 1][j ^ a[i]][2] + f[p][j][2] + f[p][j][1];
}
p ^= 1;
}
if (f[p][0][2].m[0] == 0){printf("0\n"); return 0;}
printf("%d", f[p][0][2].m[f[p][0][2].m[0]]);
for(int i = f[p][0][2].m[0] - 1; i; i--) printf("%08d", f[p][0][2].m[i]);
}

最新文章

  1. Java程序,基本数据类型、、数据类型转换、变量和常量、常用运算符
  2. Netsuite Formula &gt; Oracle函数列表速查(PL/SQL单行函数和组函数详解).txt
  3. 编译CDH Spark源代码
  4. 形行色色的下拉菜单(HTML/CSS JS方法 jQuery方法实现)
  5. C++模板详解
  6. STL总结之list
  7. Qt之自定义托盘(两种方法)
  8. zoj 2589 Matrix Searching 二维线段树
  9. EXT中导出表格中的数据到Excel
  10. C#杂记-隐式类型的局部变量
  11. KnockoutJs学习笔记(三)
  12. CSS常见Bugs及解决方案列表
  13. JavaScript高级程序设计学习(五)之对象
  14. awk对列/行进行统计求和【转】
  15. 了解一下 Linux 上用于的 SSH 图形界面工具
  16. DEV控件之ChartControl 属性设置【转】
  17. 【转】Java中JDK和JRE的区别是什么?它们的作用分别是什么?
  18. 1月10日 ruby基础教程,查漏补缺; 2月22日 Exception补充
  19. 快用Visual Studio(四)- 主题 偏好与快捷键
  20. JasperReports实现报表调出excel

热门文章

  1. .NET 6使用ImageSharp给图片添加水印
  2. log4j漏洞原理
  3. Android ViewPager2 + TabLayout + BottomNavigationView
  4. 解决PC 拖动浏览器或者应用时CPU占用过高问题
  5. Nginx rewrite 详解
  6. 把盏言欢,款款而谈,ChatGPT结合钉钉机器人(outgoing回调)打造人工智能群聊/单聊场景,基于Python3.10
  7. python运算符与基本数据类型
  8. 08-通用Service接口
  9. anaconda peompt 、labalimg 数据标注
  10. [编程基础] C++多线程入门1-创建线程的三种不同方式