题目

  点这里看题目。

分析

  我们先放宽条件,重新定义五元组\((a,b,c,d,e)\)如下:

  1.\(1\le a,b,c,d,e\le n\)。

  2.\(s_a\&s_b=1\)。

  并且设\(v(a,b,c,d,e)=(s_a|s_b)\&s_c\&(s_d\oplus s_e)\)。(这里的\(\oplus\)指代异或,下同)

  于是乎答案可以变成:

\[\begin{aligned}
&\sum_{p}\ \sum_{v(a,b,c,d,e)=2^p}\ f(s_a|s_b)\times f(s_c)\times f(s_d\oplus s_e)\\
=&\sum_{p}\ \sum_{i\& j\& k=2^p} f(i)\times \left(\sum_{a|b=i,a\& b=0}1\right)\times f(j)\times f(k)\times \left(\sum_{d\oplus e=k}1\right)
\end{aligned}
\]

  中间一层求和实际上是与卷积,内部的第一个求和是一个子集卷积,内部第二个求和是一个异或卷积。与卷积可以 FWT (或者叫 FMT ), 子集卷积可以 FST ,异或卷积可以 FWT 。总的时间复杂度为\(O(n\log_2^2n)\)( FST 最花时间 )。

   FST 实际上是 魔改 FWT 的思想,只不过为了避免分出来的子集还有交,就加了一位表示集合的大小(子集卷积满足\(A,B\subseteq S, A\cup B=S, A\cap B=\varnothing\),\(A\cap B=\varnothing\)的限制等价于\(|A|+|B|=|S|\))。

代码

  1. #include <cstdio>
  2. typedef long long LL;
  3. const int mod = 1e9 + 7, inv2 = 5e8 + 4;
  4. const int MAXN = 1e6 + 5, MAXL = ( 1 << 17 ) + 5, MAXLOG = 20;
  5. template<typename _T>
  6. void read( _T &x )
  7. {
  8. x = 0;char s = getchar();int f = 1;
  9. while( s > '9' || s < '0' ){if( s == '-' ) f = -1; s = getchar();}
  10. while( s >= '0' && s <= '9' ){x = ( x << 3 ) + ( x << 1 ) + ( s - '0' ), s = getchar();}
  11. x *= f;
  12. }
  13. template<typename _T>
  14. void write( _T x )
  15. {
  16. if( x < 0 ){ putchar( '-' ); x = ( ~ x ) + 1; }
  17. if( 9 < x ){ write( x / 10 ); }
  18. putchar( x % 10 + '0' );
  19. }
  20. template<typename _T>
  21. _T MAX( const _T a, const _T b )
  22. {
  23. return a > b ? a : b;
  24. }
  25. int f[MAXLOG][MAXL], h[MAXL];
  26. int A[MAXL], B[MAXL], C[MAXL], fibo[MAXL];
  27. int cnt[MAXL];
  28. int N, len, lg2;
  29. int lowbit( const int x ) { return x & ( -x ); }
  30. int fix( const int a ) { return ( a % mod + mod ) % mod; }
  31. int count( int x ) { int ret = 0; while( x ) ret ++, x -= lowbit( x ); return ret; }
  32. namespace OR
  33. {
  34. void FWT( int *F, const int mode )
  35. {
  36. for( int s = 2 ; s <= len ; s <<= 1 )
  37. for( int i = 0, t = s >> 1 ; i < len ; i += s )
  38. for( int j = i ; j < i + t ; j ++ )
  39. F[j + t] = fix( F[j + t] + mode * F[j] );
  40. }
  41. }
  42. namespace AND
  43. {
  44. void FWT( int *F, const int mode )
  45. {
  46. for( int s = 2 ; s <= len ; s <<= 1 )
  47. for( int i = 0, t = s >> 1 ; i < len ; i += s )
  48. for( int j = i ; j < i + t ; j ++ )
  49. F[j] = fix( F[j] + mode * F[j + t] );
  50. }
  51. }
  52. namespace XOR
  53. {
  54. void FWT( int *F, const int mode )
  55. {
  56. int t1, t2;
  57. for( int s = 2 ; s <= len ; s <<= 1 )
  58. for( int i = 0, t = s >> 1 ; i < len ; i += s )
  59. for( int j = i ; j < i + t ; j ++ )
  60. {
  61. t1 = F[j], t2 = F[j + t];
  62. if( mode > 0 ) F[j] = ( t1 + t2 ) % mod, F[j + t] = fix( t1 - t2 );
  63. else F[j] = 1ll * ( t1 + t2 ) * inv2 % mod, F[j + t] = 1ll * fix( t1 - t2 ) * inv2 % mod;
  64. }
  65. }
  66. }
  67. void FST()
  68. {
  69. for( int i = 0 ; i <= lg2 ; i ++ ) OR :: FWT( f[i], 1 );
  70. for( int i = 0 ; i <= lg2 ; i ++ )
  71. {
  72. for( int S = 0 ; S < len ; S ++ ) h[S] = 0;
  73. for( int j = 0 ; j <= i ; j ++ )
  74. for( int S = 0 ; S < len ; S ++ )
  75. h[S] = ( h[S] + 1ll * f[j][S] * f[i - j][S] % mod ) % mod;
  76. OR :: FWT( h, -1 );
  77. for( int S = 0 ; S < len ; S ++ ) if( cnt[S] == i ) A[S] = ( A[S] + h[S] ) % mod;
  78. }
  79. }
  80. void init()
  81. {
  82. fibo[0] = 0, fibo[1] = 1;
  83. for( int i = 2 ; i < ( 1 << 17 ) ; i ++ ) fibo[i] = ( fibo[i - 1] + fibo[i - 2] ) % mod;
  84. for( int i = 0 ; i < ( 1 << 17 ) ; i ++ ) cnt[i] = count( i );
  85. }
  86. signed main()
  87. {
  88. int mx = 0;
  89. read( N );
  90. init();
  91. for( int i = 1, v ; i <= N ; i ++ )
  92. {
  93. read( v ), mx = MAX( v, mx );
  94. f[cnt[v]][v] ++, C[v] ++, B[v] = ( B[v] + fibo[v] ) % mod;
  95. }
  96. for( lg2 = 0, len = 1 ; len <= mx ; len <<= 1, lg2 ++ );
  97. FST();
  98. XOR :: FWT( C, 1 );
  99. for( int i = 0 ; i < len ; i ++ ) C[i] = 1ll * C[i] * C[i] % mod;
  100. XOR :: FWT( C, -1 );
  101. for( int i = 0 ; i < len ; i ++ ) A[i] = 1ll * A[i] * fibo[i] % mod, C[i] = 1ll * C[i] * fibo[i] % mod;
  102. AND :: FWT( A, 1 ), AND :: FWT( B, 1 ), AND :: FWT( C, 1 );
  103. for( int i = 0 ; i < len ; i ++ ) A[i] = 1ll * A[i] * B[i] % mod * C[i] % mod;
  104. AND :: FWT( A, -1 );
  105. int ans = 0;
  106. for( int i = 1 ; i <= len ; i <<= 1 ) ( ans += A[i] ) %= mod;
  107. write( ans ), putchar( '\n' );
  108. return 0;
  109. }

[CF914D]Sum the Fibonacci的更多相关文章

  1. 【CF914G】Sum the Fibonacci 快速??变换模板

    [CF914G]Sum the Fibonacci 题解:给你一个长度为n的数组s.定义五元组(a,b,c,d,e)是合法的当且仅当: 1. $1\le a,b,c,d,e\le n$2. $(s_a ...

  2. CF914G Sum the Fibonacci(FWT,FST)

    CF914G Sum the Fibonacci(FWT,FST) Luogu 题解时间 一堆FWT和FST缝合而来的丑陋产物. 对 $ cnt[s_{a}] $ 和 $ cnt[s_{b}] $ 求 ...

  3. Codecraft-18 and Codeforces Round #458 (Div. 1 + Div. 2, combined)G. Sum the Fibonacci

    题意:给一个数组s,求\(f(s_a | s_b) * f(s_c) * f(s_d \oplus s_e)\),f是斐波那契数列,而且要满足\(s_a\&s_b==0\),\((s_a | ...

  4. 【codeforces914G】Sum the Fibonacci FWT+FST(快速子集变换)

    题目描述 给出一个长度为 $n$ 的序列 $\{s\}$ ,对于所有满足以下条件的五元组 $(a,b,c,d,e)$ : $1\le a,b,c,d,e\le n$ : $(s_a|s_b)\& ...

  5. codeforces914G Sum the Fibonacci

    题目大意:给定一个长为$n$($n\leq 10^6$)的序列S,定义一个合法的五元组$(a,b,c,d,e)$合法当且仅当 $$ ( S_a \mid S_b ) and S_c and ( S_d ...

  6. CF 914 G Sum the Fibonacci —— 子集卷积,FWT

    题目:http://codeforces.com/contest/914/problem/G 其实就是把各种都用子集卷积和FWT卷起来算即可: 注意乘 Fibonacci 数组的位置: 子集卷积时不能 ...

  7. 题解 CF914G Sum the Fibonacci

    题目传送门 题目大意 给出\(n,s_{1,2,...,n}\),定义一个五元组\((a,b,c,d,e)\)合法当且仅当: \[1\le a,b,c,d,e\le n \] \[(s_a\vee s ...

  8. CF914G Sum the Fibonacci FWT、子集卷积

    传送门 一道良心的练习FWT和子集卷积的板子-- 具体来说就是先把所有满足\(s_a \& s_b = 0\)的\(s_a \mid s_b\)的值用子集卷积算出来,将所有\(s_a \opl ...

  9. CF914G Sum the Fibonacci

    解:发现我们对a和b做一个集合卷积,对d和e做一个^FWT,然后把这三个全部对位乘上斐波那契数,然后做&FWT就行了. #include <bits/stdc++.h> , MO ...

随机推荐

  1. jquery.autocomplete的使用-----------------------摘抄别人的

    作者:lxhwss | 2011/10/11 9:46:38 | 阅读43次 document.write(”<script language=javascript src=’/js/2.js’ ...

  2. 苏浪浪 201771010120《面向对象程序设计(java)》第八周学习总结

    1.实验目的与要求 (1) 掌握接口定义方法: (2) 掌握实现接口类的定义要求: (3) 掌握实现了接口类的使用要求: (4) 掌握程序回调设计模式: (5) 掌握Comparator接口用法: ( ...

  3. 限制某个顶点度数的最小生成树 poj1639

    Picnic Planning Time Limit: 5000MS   Memory Limit: 10000K Total Submissions: 10642   Accepted: 3862 ...

  4. (STL初步)映射:map

    map就是从键(key)到值(value)的映射. 因为重载了[]运算符,map像是数组的”高级版“. 例如,map<string,int>month_name 表示:”月份名字到月份编号 ...

  5. 仿开源框架从零到一完整实现高性能、可扩展的RPC框架 | 6个月做成教程免费送

    去年年就在写一本付费小册,今年年初基本上就写完了,本来预计计划是春节上线结果由于平台的原因一直拖着没上.五一前跟平台联系给的反馈是五月份能上,结果平台又在重构,停止小册的申请和上线,最后我考虑了一下决 ...

  6. SVN强制添加备注

    1.进入仓库project1/hooks目录,找到pre-commit.tmpl文件 cp pre-commit.tmpl pre-commit 2.编辑pre-commit文件, 将: $SVNLO ...

  7. Cypress系列(1)- Window下安装 Cypress 并打开

    如果想从头学起Cypress,可以看下面的系列文章哦 https://www.cnblogs.com/poloyy/category/1768839.html 系统要求 Cypress 是一个被安装在 ...

  8. day20 函数闭包与装饰器

    装饰器:本质就是函数,功能是为其他函数添加新功能 原则: 1.不修改被装饰函数的源代码(开放封闭原则) 2.为被装饰函数添加新功能后,不修改被修饰函数的调用方式 装饰器的知识储备: 装饰器=高阶函数+ ...

  9. Bank3

    Account: package banking3; //账户 public class Account { private double balance;// 账户余额 public Account ...

  10. ## H5 canvas画图白板踩坑

    最近接手了一个小型的H5,最主要的功能大概就是拍照上传和canvas画板了. 主要是记录一下自己菜到像傻子一样的技术. 1.canvas画板隔空打牛!画布越往上部分错位距离越小,越往下距离越大. 2. ...