jzoj. 3889. 【NOIP2014模拟10.25B组】序列问题
来源:互联网 发布:国安数据 编辑:程序博客网 时间:2024/06/14 09:17
Description
小H是个善于思考的学生,她正在思考一个有关序列的问题。
她的面前浮现出了一个长度为n的序列{ai},她想找出两个非空的集合S、T。
这两个集合要满足以下的条件:
两个集合中的元素都为整数,且都在 [1, n] 里,即Si,Ti ∈ [1, n]。
对于集合S中任意一个元素x,集合T中任意一个元素y,满足x < y。
对于大小分别为p, q的集合S与T,满足 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),你能帮助她吗?
Input
第一行,一个整数n
第二行,n个整数,代表ai。
Output
仅一行,表示最后的答案。
Sample Input
4
1 2 3 3
Sample Output
4
【样例解释】
S = {1,2}, T = {3}, 1 ^ 2 = 3 = 3 (^为异或)
S = {1,2}, T = {4}, 1 ^ 2 = 3 = 3
S = {1,2}, T = {3,4} 1 ^ 2 = 3 & 3 = 3 (&为与运算)
S = {3}, T = {4} 3 = 3 = 3
Data Constraint
30%: 1 <= n <= 10
60%: 1 <= n <= 100
100%: 1 <= n <= 1000, 0 <= ai < 1024
分析:
30%:枚举每个数所在的集合或者不选,然后判定即可。复杂度 O(n*3^n)。
60%: Dp,两个数相等就相当于两个数的 xor 为 0。设 f[i][j][k=0..2]代表 处理到第 I 个数,
如果 k = 1 代表 and 值为 j,如果 k = 2 代表 xor 值为 j,如果 k = 0 则代表一个元素都没
取。所以很容易得到方程:
f[i][j][0] = f[i + 1][j][0]
f[i][j & ai][1] = f[i + 1][j][1] + f[i + 1][j][0] + f[i + 1][j & ai][1]
f[i][j ^ ai][2] = f[i + 1][j][1] + f[i + 1][j][2] + f[i + 1][j ^ ai][2];
最后 f[1][0][2]就是答案, 复杂度为 O(n * 1024 * 3)
DP 还可以分开用 f[i][j]和 g[i][j]表示前 i 个 xor 值为 j,后 i 个 and 值为 j 的方案数,
随后枚举分界点 k 来求总方案数。复杂度 O(n * 1024 * 3)。
100%:满分数据需要高精,答案位数较大,需要进行压位来防止 TLE,因为不知道答案的
位数究竟多大,压位后高精数组仍需要开的较大一些,所以原 DP 的数组滚动即可。
代码:
const mo=100000000;type arr=array[0..40] of longint;var n,i,j,p,q:longint; st:string; a:array[1..1000] of longint; f:array[0..1,0..1023,1..2,0..40] of longint;function max(x,y:longint):longint;begin if x>y then exit(x) else exit(y);end;procedure plus(var x:arr;y:arr);var i:longint;begin for i:=1 to max(x[0],y[0]) do begin x[i]:=x[i]+y[i]; x[i+1]:=x[i+1]+x[i] div mo; x[i]:=x[i] mod mo; end; x[0]:=max(x[0],y[0]); if x[x[0]+1]>0 then inc(x[0]);end;begin readln(n); for i:=1 to n do read(a[i]); for i:=n downto 1 do begin p:=i mod 2; q:=(i+1) mod 2; f[p][a[i]][1][0]:=1; f[p][a[i]][1][1]:=1; for j:=0 to 1023 do begin plus(f[p][j][1],f[q][j][1]); plus(f[p][j and a[i]][1],f[q][j][1]); plus(f[p][j][2],f[q][j][2]); plus(f[p][j xor a[i]][2],f[q][j][2]); plus(f[p][j xor a[i]][2],f[q][j][1]); end; fillchar(f[q],sizeof(f[q]),0); end; for i:=f[1][0][2][0] downto 1 do begin str(f[1][0][2][i],st); if i<>f[1][0][2][0] then for j:=1 to 8-length(st) do st:='0'+st; write(st); end; if f[1][0][2][0]=0 then writeln(0);end.
- jzoj. 3889. 【NOIP2014模拟10.25B组】序列问题
- [jzoj]3889. 【NOIP2014模拟10.25B组】序列问题(DP的各种方法+细节+详细分析)
- [jzoj3889]【NOIP2014模拟10.25B组】序列问题
- jzoj NOIP2014提高组模拟8.9总结
- JZOJ NOIP2014模拟 8.12
- JZOJ NOIP2014模拟 8.13
- [JZOJ 3794]. 【NOIP2014模拟8.20】高级打字机
- 【JZOJ】 【NOIP2014】【模拟试题】保镖排队
- JZOJ 3808. 【NOIP2014模拟8.25】道路值守
- JZOJ 3807. 【NOIP2014模拟8.25】地砖铺设
- JZOJ 3807. 【NOIP2014模拟8.25】地砖铺设
- JZOJ 3809. 【NOIP2014模拟8.25】设备塔
- JZOJ 3809. 【NOIP2014模拟8.25】设备塔
- JZOJ 3814. 【NOIP2014模拟9.7】天黑黑
- JZOJ 3823. 【NOIP2014模拟9.9】遇见
- JZOJ 3822. 【NOIP2014模拟9.9】逆光
- JZOJ 3823【NOIP2014模拟9.9】遇见
- JZOJ 3824【NOIP2014模拟9.9】渴
- 《ISLR》交叉验证与自助法
- java 小知识 关系运算符的全面总结
- Linux下C/C++帮助手册安装方法 及使用方法
- c/c++整理--函数重载
- Java可变参数(转载)
- jzoj. 3889. 【NOIP2014模拟10.25B组】序列问题
- NIO非阻塞通信服务端部分代码
- hdu 2546 饭卡
- css样式
- 暴搜——51nod1400 序列分解
- java运算符之++、--
- 验证对象在创建时就会先调用(默认)构造方法
- 十分钟搞清字符集和字符编码
- STM32 心电滤波