zoukankan      html  css  js  c++  java
  • 题解 CF914G Sum the Fibonacci

    题目传送门

    题目大意

    给出(n,s_{1,2,...,n}),定义一个五元组((a,b,c,d,e))合法当且仅当:

    1. [1le a,b,c,d,ele n ]

    2. [(s_avee s_b)wedge s_c wedge (s_doplus s_e)=2^i,iin mathbb{Z} ]

    3. [s_awedge s_b=0 ]

    求出对于所有合法的五元组((a,b,c,d,e)):

    [sum f(s_avee s_b)f(s_c)f(s_doplus s_e) ]

    其中(f(i))表示第(i)位斐波拉契数列。

    思路

    其实这个题应该算( ext {FST})的入门级题目,也不是很难。

    首先,我们定义(v(a,b,c,d,e)=(s_avee s_b)wedge s_c wedge (s_doplus s_e))。于是我们可以把式子写成这样一个形式:

    [sum_{i} sum_{v(a,b,c,d,e)=2^i} [s_awedge s_b=0]f(s_avee s_b)f(s_c)f(s_doplus s_e) ]

    [=sum_{p} sum_{iwedge jwedge k=2^p} f(i)f(j)f(k)(sum_{s_avee s_b=i,s_awedge s_b=0}1)(sum_{s_aoplus s_b=k}1) ]

    然后我们就发现第一个括号里面的可以用子集卷积求到,后面那个可以用异或卷积求到,总的又可以用并卷积求到。于是我们就可以在(Theta(wlog ^2w))的时间内求到了。其中(w)是值域。

    ( ext {Code})

    #include <bits/stdc++.h>
    using namespace std;
    
    #define Int register int
    #define inv2 500000004
    #define mod 1000000007
    #define MAXN 1000005
    
    template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
    template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
    template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
    
    int lim = 1; 
    
    void mul (int &a,int b){a = 1ll * a * b % mod;}
    void del (int &a,int b){a = a >= b ? a - b : a + mod - b;}
    void add (int &a,int b){a = a + b >= mod ? a + b - mod : a + b;}
    
    void ORFWT (int *A,int type){
    	for (Int i = 1;i < lim;i <<= 1)
    		for (Int j = 0;j < lim;j += i << 1)
    			for (Int k = 0;k < i;++ k)
    				if (type == 1) add (A[i + j + k],A[j + k]);
    				else del (A[i + j + k],A[j + k]);
    }
    
    void ANDFWT (int *A,int type){
    	for (Int i = 1;i < lim;i <<= 1)
    		for (Int j = 0;j < lim;j += i << 1)
    			for (Int k = 0;k < i;++ k)
    				if (type == 1) add (A[j + k],A[i + j + k]);
    				else del (A[j + k],A[i + j + k]);
    }
    
    void XORFWT (int *A,int type){
    	for (Int i = 1;i < lim;i <<= 1)
    		for (Int j = 0;j < lim;j += i << 1)
    			for (Int k = 0;k < i;++ k){
    				int x = A[j + k],y = A[i + j + k];
    				if (type == 1) A[j + k] = (x + y) % mod,A[i + j + k] = (x + mod - y) % mod;
    				else A[j + k] = 1ll * (x + y) * inv2 % mod,A[i + j + k] = 1ll * (x + mod - y) * inv2 % mod;
    			}
    }
    
    int n,s,fib[1 << 17],cnt[1 << 17],A[1 << 17],S[1 << 17],f[18][1 << 17],h[1 << 17],sum[1 << 17];
    
    signed main(){
    	read (n);
    	fib[0] = 0,fib[1] = cnt[1] = 1;int maxn = 0;
    	for (Int i = 2;i < (1 << 17);++ i) fib[i] = (fib[i - 1] + fib[i - 2]) % mod,cnt[i] = cnt[i >> 1] + (i & 1);
    	for (Int i = 1,s;i <= n;++ i) read (s),maxn = max (maxn,s),add (f[cnt[s]][s],1),add (h[s],1),add (sum[s],fib[s]);
    	int logn = 0;while (lim <= maxn) lim <<= 1,logn ++;
    	for (Int i = 0;i <= logn;++ i) ORFWT (f[i],1);
    	for (Int i = 0;i <= logn;++ i){
    		for (Int j = 0;j < lim;++ j) S[j] = 0;
    		for (Int j = 0;j <= i;++ j)
    			for (Int k = 0;k < lim;++ k)
    				add (S[k],1ll * f[j][k] * f[i - j][k] % mod);
    		ORFWT (S,-1);
    		for (Int j = 0;j < lim;++ j) if (cnt[j] == i) add (A[j],S[j]); 
    	}
    	XORFWT (h,1); 
    	for (Int i = 0;i < lim;++ i) mul (h[i],h[i]);
    	XORFWT (h,-1);
    	for (Int i = 0;i < lim;++ i) mul (A[i],fib[i]),mul (h[i],fib[i]);
    	ANDFWT (A,1),ANDFWT (h,1),ANDFWT (sum,1);
    	for (Int i = 0;i < lim;++ i) mul (A[i],h[i]),mul (A[i],sum[i]);
    	ANDFWT (A,-1);
    	int ans = 0;for (Int i = 1;i < lim;i <<= 1) add (ans,A[i]);
    	write (ans),putchar ('
    ');
    	return 0;
    }
    
  • 相关阅读:
    全面分析 Spring 的编程式事务管理及声明式事务管理
    100句唤醒自己的励志名言
    100句自我激励的名言佳句
    java反射详解
    JAVA中的反射机制
    【BZOJ1015】【JSOI2008】星球大战Starwar(离线并差集)
    【HEOI2016/TJOI2016】排序(二份答案+线段树)
    【USACO06DEC】—牛奶模式Milk Patterns(后缀自动机)
    【HNOI2016】—找相同字符(后缀自动机)
    【AHOI2013】—差异(后缀自动机)
  • 原文地址:https://www.cnblogs.com/Dark-Romance/p/13254351.html
Copyright © 2011-2022 走看看