【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|s_b) \& s_c \& (s_d $^$ s_e)=2^i$,i是某个整数
3. $s_a \& s_b=0$

求$\sum f(s_a|s_b) * f(s_c) * f(s_d $^$ s_e)$,f是斐波那契数列,对于所有合法的五元组(a,b,c,d,e)。答案模$10^9+7$。

$1\le n\le 10^6,0\le s_i< 2^17$

题解:说白了就是求:子集和卷积,异或卷积,与卷积。后面两个好求,学了一发子集和卷积。说白了就是强行加了一个占位多项式,即将数组多开一维记录子集中1的个数。然后合并时相当于背包合并,时间复杂度$O(n^22^n)$。

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;

typedef long long ll;
const int maxn=(1<<17)+4;
const ll P=1000000007;
const ll inv=500000004;
ll a[maxn],c[maxn],d[maxn];
ll fa[maxn][18],fb[maxn][18],f[maxn];
ll ans;
int cnt[maxn];
int n,len;
inline int rd()
{
	int ret=0,f=1;	char gc=getchar();
	while(gc<‘0‘||gc>‘9‘)	{if(gc==‘-‘)	f=-f;	gc=getchar();}
	while(gc>=‘0‘&&gc<=‘9‘)	ret=ret*10+gc-‘0‘,gc=getchar();
	return ret*f;
}
int main()
{
	n=rd();
	int h,i,j,k,x,y,v;
	f[1]=cnt[1]=1;
	len=1<<17;
	for(i=2;i<len;i++)	f[i]=(f[i-1]+f[i-2])%P,cnt[i]=cnt[i-(i&-i)]+1;
	for(i=1;i<=n;i++)	v=rd(),fa[v][cnt[v]]++,d[v]++,c[v]=(c[v]+f[v])%P;
	for(h=1;h<len;h<<=1)	for(i=0;i<len;i++)	if(i&h)	for(j=0;j<=17;j++)
		fa[i][j]=(fa[i][j]+fa[i-h][j])%P;
	for(i=0;i<len;i++)	for(j=0;j<=17;j++)	for(k=0;k<=j;k++)
		fb[i][j]=(fb[i][j]+fa[i][k]*fa[i][j-k])%P;
	for(h=1;h<len;h<<=1)	for(i=0;i<len;i++)	if(i&h)	for(j=0;j<=17;j++)
		fb[i][j]=(fb[i][j]-fb[i-h][j]+P)%P;
	for(i=0;i<len;i++)	a[i]=(a[i]+f[i]*fb[i][cnt[i]])%P;
	for(h=1;h<len;h<<=1)	for(i=0;i<len;i++)	if(i&h)
		x=d[i-h],y=d[i],d[i-h]=(x+y)%P,d[i]=(x-y+P)%P;
	for(i=0;i<len;i++)	d[i]=d[i]*d[i]%P;
	for(h=1;h<len;h<<=1)	for(i=0;i<len;i++)	if(i&h)
		x=d[i-h],y=d[i],d[i-h]=(x+y)*inv%P,d[i]=(x-y+P)*inv%P;
	for(i=0;i<len;i++)	d[i]=d[i]*f[i]%P;
	for(h=1;h<len;h<<=1)	for(i=0;i<len;i++)	if(!(i&h))
		a[i]=(a[i]+a[i+h])%P,c[i]=(c[i]+c[i+h])%P,d[i]=(d[i]+d[i+h])%P;
	for(i=0;i<len;i++)	a[i]=a[i]*c[i]%P*d[i]%P;
	for(h=1;h<len;h<<=1)	for(i=0;i<len;i++)	if(!(i&h))
		a[i]=(a[i]-a[i+h]+P)%P;
	for(i=0;i<17;i++)	ans=(ans+a[1<<i])%P;
	printf("%lld",ans);
	return 0;
}

原文地址:https://www.cnblogs.com/CQzhangyu/p/8445258.html

时间: 2024-11-10 19:11:49

【CF914G】Sum the Fibonacci 快速??变换模板的相关文章

CF914G Sum the Fibonacci FWT、子集卷积

传送门 一道良心的练习FWT和子集卷积的板子-- 具体来说就是先把所有满足\(s_a \& s_b = 0\)的\(s_a \mid s_b\)的值用子集卷积算出来,将所有\(s_a \oplus s_b\)用xor卷积算出来,把斐波那契数代进去,然后将三个数组and卷积,最后取\(2^i (i \in Z)\)的位置的答案的和 #include<bits/stdc++.h> //this code is written by Itst using namespace std; int

HDU 3306 Another kind of Fibonacci(快速幂矩阵)

题目链接 构造矩阵 看的题解,剩下的就是模板了,好久没写过了,注意取余. #include <cstring> #include <cstdio> #include <string> #include <iostream> #include <algorithm> #include <vector> #include <queue> using namespace std; #define MOD 10007 #defin

矩阵快速幂模板篇

转载请注明出处:http://blog.csdn.net/u012860063 或许你们看不太懂,纯属自用: 第一种: Description Let's define another number sequence, given by the following function: f(0) = a f(1) = b f(n) = f(n-1) + f(n-2), n > 1 When a = 0 and b = 1, this sequence gives the Fibonacci seq

矩阵快速幂 模板

矩阵快速幂模板 1 #include<stdio.h> 2 #include<math.h> 3 #include<set> 4 #include<string.h> 5 using namespace std; 6 int const mod=1e9+7; 7 struct matrix 8 { 9 long long m[3][3]; 10 matrix() 11 { 12 memset(m,0,sizeof(m)); 13 } 14 matrix op

POJ 1995 Raising Modulo Numbers (快速幂模板)

Raising Modulo Numbers Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 4938   Accepted: 2864 Description People are different. Some secretly read magazines full of interesting girls' pictures, others create an A-bomb in their cellar, oth

矩阵快速幂 模板与简单讲解

模板 快速幂模板 1 void solve(matrix t,long long o) 2 { 3 matrix e; 4 5 memset(e.a,0,sizeof(e.a)); 6 7 for (int i = 0;i < d;i++) 8 e.a[i][i] = 1; 9 10 while (o) 11 { 12 if (o & 1) 13 { 14 e = mul(e,t); 15 } 16 17 o >>= 1; 18 19 t = mul(t,t); 20 } 21

51nod1113(矩阵快速幂模板)

题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1113 题意:中文题诶- 思路:矩阵快速幂模板 代码: 1 #include <iostream> 2 #define ll long long 3 using namespace std; 4 5 const int mod = 1e9+7; 6 const int MAXN = 1e2+10; 7 int n, m; 8 9 typedef struct

一种简单快速的模板解析方法,活用with javascript版

//一种简单快速的模板解析方法,活用with var parseTpl = function( str, data ) { var tmpl = 'var __p=[];' + 'with(obj||{}){__p.push(\'' + str.replace( /\\/g, '\\\\' ) .replace( /'/g, '\\\'' ) .replace( /<%=([\s\S]+?)%>/g, function( match, code ) { return '\',' + code.

快速幂和矩阵快速幂模板

快速幂模板: ll qmod(ll x,ll n,ll mod) { ll res=1; while(n){ if(n&1) res=(res*x)%mod; x=(x*x)%mod; n/=2; } return res; } 例题:hdu 1097 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> usin