• 题解 黎明前的巧克力


    题目传送门

    题目大意

    初始有两个数 (a,b) ,有 (n) 次操作,每次提供一个数 (a_i) ,要么不操作,要么从 (a,b) 中选一个数异或上 (a_i) ,问最后 (a,b) 相同的方案数。

    (n,a_ile 10^6)

    思路

    不难看出如果我们设 (x=aoplus b) ,那么每次操作就是 (xgets xoplus a_i) ,于是我们可以想到使用 ( exttt{FWT}) 解决这个问题。我们发现最后的答案其实就是:

    [[x^0]igoplus_{i=1}^{n}(1+2x^{a_i})-1 ]

    (减 (1) 是因为题目要求不能不操作,尽管这显得非常多此一举)

    然后我们就发现直接 ( exttt{FWT}) 铁定 gg ,然后我们考虑到有值得数位很少,可以联想到 CF1119H Triple ,我们发现 ( exttt{FWT}[i]) 要么为 (-1) 要么为 (3) ,因为 (1) 产生的贡献一定为 (1) ,而 (2x^{a_i}) 产生的贡献一定为 (pm 2)

    于是,我们的问题就是对于每一位知道有多少个 (3) (因为 (3) 的个数和 (-1) 的个数之和一定为 (n))。我们设这个东西为 (x) ,我们发现如果设

    [f_i= exttt{FWT}(sum_{i=1}^{n}(1+2x^{a_i}))[i] ]

    那我们就有等式:

    [(-x)+3(n-x)=f_i ]

    于是我们就可以解出 (x) 了 。然后我们将这个东西带回去,( exttt{IDWT}) 一遍就好了。

    时间复杂度 (Theta(nlog^2 n)),假设 (n) 与值域同阶。

    ( exttt{Code})

    #include <bits/stdc++.h>
    using namespace std;
    
    #define Int register int
    #define mod 998244353
    #define MAXN 1048576
    
    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 n,maxf,inv2,inv4,logn,g[MAXN],aa[MAXN],pw[MAXN];
    int mul (int a,int b){return 1ll * a * b % mod;}
    int dec (int a,int b){return a >= b ? a - b : a + mod - b;}
    int add (int a,int b){return a + b >= mod ? a + b - mod : a + b;}
    int qkpow (int a,int b){
    	int res = 1;for (;b;b >>= 1,a = mul (a,a)) if (b & 1) res = mul (res,a);
    	return res;
    }
    
    void FWT (int *f,int n){
    	for (Int i = 1;i < n;i <<= 1)
    		for (Int j = 0;j < n;j += i << 1)
    			for (Int k = 0;k < i;++ k){
    				int x = f[j + k],y = f[i + j + k];
    				f[j + k] = add (x,y),f[i + j + k] = dec (x,y);
    			} 
    }
    
    void IFWT (int *f,int n){
    	for (Int i = 1;i < n;i <<= 1)
    		for (Int j = 0;j < n;j += i << 1)
    			for (Int k = 0;k < i;++ k){
    				int x = f[j + k],y = f[i + j + k];
    				f[j + k] = mul (inv2,add (x,y)),f[i + j + k] = mul (inv2,dec (x,y));
    			} 
    }
    
    signed main(){
    	read (n),pw[0] = 1;
    	inv2 = qkpow (2,mod - 2),inv4 = qkpow (4,mod - 2);
    	for (Int i = 1;i <= n;++ i) pw[i] = mul (pw[i - 1],3); 
    	for (Int i = 1,ai;i <= n;++ i) read (ai),g[0] ++,g[ai] += 2,maxf = max (maxf,ai);
    	while ((1 << logn) <= maxf) logn ++;
    	FWT (g,1 << logn);
    	for (Int i = 0;i < 1 << logn;++ i) {
    		int x = mul (dec (3 * n,g[i]),inv4);
    		g[i] = mul (x & 1 ? (mod - 1) : 1,pw[n - x]);
    	}
    	IFWT (g,1 << logn);
    	write (dec (g[0],1)),putchar ('
    ');
     	return 0;
    }
    
  • 相关阅读:
    jquery常用语句
    记录一个奇异的问题
    冰块渲染2
    冰块渲染
    GCAlloc 问题一则
    矩阵基础3
    优化 Overdraw 和 GrabPass
    优化平面法线贴图
    环境模拟
    使用 GPU 加速计算
  • 原文地址:https://www.cnblogs.com/Dark-Romance/p/13535695.html
Copyright © 2020-2023  润新知