首页 > 其他分享 >CF1119H Triple 题解

CF1119H Triple 题解

时间:2024-09-25 15:45:15浏览次数:1  
标签:kMod cnt le CF1119H int 题解 Triple FWT inline

Description

SK 酱送给你了一份生日礼物。礼物是 \(n\) 个三元组 \((a_i,b_i,c_i)\) 和四个正整数 \(x,y,z,k\)。

你利用这 \(n\) 个三元组填充了 \(n\) 个数组,其中第 \(i\) 个数组中有 \(x\) 个 \(a_i\),\(y\) 个 \(b_i\),\(z\) 个 \(c_i\)(所以第 \(i\) 个数组长度为 \((x+y+z)\)。

对于 \(i=0,1,\cdots,2^k-1\),回答以下询问:

  • 从每个数组中选择恰好一个数,使得这些数的 \(\mathrm{xor}\) 和为 \(i\),方案数是多少?

你只需要输出方案数对 \(998,244,353\) 取模后得到的结果。

对于 \(100\%\) 的数据,保证:

  • \(1\le n\le 10^5\),\(1\le k\le 17\);
  • \(0\le x,y,z\le 10^9\);
  • \(0\le a_i,b_i,c_i\lt 2^k\)。

Solution

首先先让 \(b_i\) 和 \(c_i\) 都异或上 \(a_i\),这样就转化为了 \(a_i\) 等于 \(0\) 的情况。

容易发现这是个 FWT 的形式,设 \(cnt(i)=popcount(i)\),\(FWT_k[i]\) 表示 \((a_k,b_k,c_k)\) 的 FWT 数组,那么 \(FWT_k[i]=(-1)^{cnt(i\&a_k)}x+(-1)^{cnt(i\&b_k)}y+(-1)^{cnt(i\&c_k)}z\)。

由于 \(a_k=0\),所以第一项为 \(x\),即 \(FWT_k[i]=x+(-1)^{cnt(i\&b_k)}y+(-1)^{cnt(i\&c_k)}z\)。

这里的 \(FWT_k[i]\) 只有 \(4\) 种可能,分别是 \(x+y+z,x+y-z,x-y+z,x-y-z\),设这四种分别出现了 \(c_1,c_2,c_3,c_4\) 次。考虑用解方程的方式解出这四个数。

第一个式子是 \(c_1+c_2+c_3+c_4=n\)。

先设 \(f_{1,k}[i]=(-1)^{cnt(i\&b_k)}\),则 \(c_1+c_2-c_3-c_4=\sum_{k=1}^{n}{f_{1,k}[i]}\)。

同理设 \(f_{2,k}[i]=(-1)^{cnt(i\&c_k)}\),则 \(c_1-c_2+c_3-c_4=\sum_{k=1}^{n}{f_{2,k}[i]}\)。

然后设 \(f_{3,k}[i]=(-1)^{cnt(i\&b_k)+cnt(i\&c_k)}\),则 \(c_1-c_2-c_3+c_4=\sum_{k=1}^{n}{f_{3,k}[i]}\)。

可以用 FWT 分别求出 \(f_{1,k}[i],f_{2,k}[i],f_{3,k}[i]\) 的和,乘起来后再 FWT 回去就是答案。

时间复杂度:\(O(n+2^kk)\)。

Code

#include <bits/stdc++.h>

#define int int64_t

const int kMaxN = 1e5 + 5, kMaxS = (1 << 17), kMod = 998244353, kInv2 = (kMod + 1) / 2;

int n, k, x, y, z, sum;
int a[kMaxN], b[kMaxN], c[kMaxN];
int f[kMaxS], f1[kMaxS], f2[kMaxS], f3[kMaxS];

constexpr int qpow(int bs, int64_t idx = kMod - 2) {
  int ret = 1;
  for (; idx; idx >>= 1, bs = (int64_t)bs * bs % kMod)
    if (idx & 1)
      ret = (int64_t)ret * bs % kMod;
  return ret;
}

inline int fix(int x) { return (x % kMod + kMod) % kMod; }
inline int add(int x, int y) { return (x + y >= kMod ? x + y - kMod : x + y); }
inline int sub(int x, int y) { return (x >= y ? x - y : x - y + kMod); }
inline void inc(int &x, int y) { (x += y) >= kMod ? x -= kMod : x; }
inline void dec(int &x, int y) { (x -= y) < 0 ? x += kMod : x; }

void FWT(int *a, int n) {
  for (int len = 2; len <= n; len <<= 1) {
    int m = len / 2;
    for (int i = 0; i < n; i += len) {
      for (int j = i; j < i + m; ++j) {
        int tmp = a[j];
        a[j] = add(a[j], a[j + m]);
        a[j + m] = sub(tmp, a[j + m]);
      }
    }
  }
}

void IFWT(int *a, int n) {
  for (int len = 2; len <= n; len <<= 1) {
    int m = len / 2;
    for (int i = 0; i < n; i += len) {
      for (int j = i; j < i + m; ++j) {
        int tmp = a[j];
        a[j] = 1ll * kInv2 * add(a[j], a[j + m]) % kMod;
        a[j + m] = 1ll * kInv2 * sub(tmp, a[j + m]) % kMod;
      }
    }
  }
}

void dickdreamer() {
  std::cin >> n >> k >> x >> y >> z;
  for (int i = 1; i <= n; ++i) {
    std::cin >> a[i] >> b[i] >> c[i];
    sum ^= a[i], b[i] ^= a[i], c[i] ^= a[i];
    ++f1[b[i]], ++f2[c[i]], ++f3[b[i] ^ c[i]];
  }
  FWT(f1, (1 << k)), FWT(f2, (1 << k)), FWT(f3, (1 << k));
  for (int i = 0; i < (1 << k); ++i) {
    int c1, c2, c3, c4;
    c1 = fix(n + f1[i] + f2[i] + f3[i]) / 4;
    c2 = fix(n + f1[i] - f2[i] - f3[i]) / 4;
    c3 = fix(n - f1[i] + f2[i] - f3[i]) / 4;
    c4 = fix(n - f1[i] - f2[i] + f3[i]) / 4;
    f[i] = 1;
    f[i] = 1ll * f[i] * qpow(fix(x + y + z), c1) % kMod;
    f[i] = 1ll * f[i] * qpow(fix(x + y - z), c2) % kMod;
    f[i] = 1ll * f[i] * qpow(fix(x - y + z), c3) % kMod;
    f[i] = 1ll * f[i] * qpow(fix(x - y - z), c4) % kMod;
  }
  IFWT(f, (1 << k));
  for (int i = 0; i < (1 << k); ++i) std::cout << f[i ^ sum] << ' ';
}

int32_t main() {
#ifdef ORZXKR
  freopen("in.txt", "r", stdin);
  freopen("out.txt", "w", stdout);
#endif
  std::ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0);
  int T = 1;
  // std::cin >> T;
  while (T--) dickdreamer();
  // std::cerr << 1.0 * clock() / CLOCKS_PER_SEC << "s\n";
  return 0;
}

标签:kMod,cnt,le,CF1119H,int,题解,Triple,FWT,inline
From: https://www.cnblogs.com/Scarab/p/18431514

相关文章

  • Codeforces Round 974 (Div. 3)题解记录
    A.RobinHelps签到模拟,遍历一遍即可,注意没钱时不给钱。\(O(n)\)#include<iostream>#include<set>#include<map>#include<vector>#include<algorithm>#include<bitset>#include<math.h>#include<string>#include<string.h>#......
  • [ARC122E] Increasing LCMs 题解
    感觉像比较套路的构造题。思路假如我们正着进行构造,可以发现我们加入一个数以后,对后面的数产生的影响是很大的。但是如果我们从最后一个数开始构造,那么可以发现它是不会对之后的构造产生任何影响的。应为越前面的数的限制会越少,那么可以填的数一定是不减的。一个数可以填在后......
  • 算法题之图论 [NOIP2001 提高组] Car的旅行路线详细题解
    P1027[NOIP2001提高组]Car的旅行路线这道题的思路呢,就是建个图,然后跑一遍Floyd,比较最小值就可以解决了。but!它每个城市只给三个点(共四个),所以还得计算出第四个点坐标。这里根据矩形的中点公式来表示未知点的坐标:(这个思路源于大佬 _jimmywang_       ......
  • [ARC121E] Directed Tree 题解
    简单容斥题。思路题面的条件相当于一个位置上填的点不能是自己的祖先。发现直接做并不好做。考虑容斥。我们想要求出\(f_i\)为至少有\(i\)个不合法位置的方案数。那么答案为:\[\sum_{i=0}^nf_i(-1)^i\]如何求解。设\(f_{i,j}\)为\(i\)子树下有\(j\)个不合法位......
  • 2024-2025专题一题单 - 题解
    A-Virus原题链接题解B-Coverage原题链接题解C-Sensors原题链接题解D-MakeTakahashiHappy原题链接题解E-Don’tbecycle原题链接题解F-AlmostEqual原题链接题解G-StepUpRobot原题链接题解H-SnukeMaze原题链接题解I-MEX原题链接......
  • P5329 [SNOI2019] 字符串 题解
    Description给出一个长度为\(n\)的由小写字母组成的字符串\(a\),设其中第\(i\)个字符为\(a_i\(1\leqi\leqn)\)。设删掉第\(i\)个字符之后得到的字符串为\(s_i\),请按照字典序对\(s_1,s_2,……,s_n\)从小到大排序。若两个字符串相等,则认为编号小的字符串字典序更小。......
  • CF164D Minimum Diameter 题解
    最小点覆盖模板题。思路考虑二分直径\(x\)。我们将距离\(>x\)的点对连一条边,那么每一条边的两端至少有一端需要被删掉。这是最小点覆盖的定义。那么就是判断最小点覆盖是否小于等于\(k\)。发现这个问题并不好用一些多项式复杂度的做法解决。考虑暴搜。每一次我们把度......
  • CF2003F Turtle and Three Sequences 题解
    个人觉得*2800有点虚高。如果做过类似的题(比如[THUSCH2017]巧克力),应该可以想到随机映射,状压dp也不难想。实际上,看到要选出\(m\)种不同的颜色,且\(m\le5\)就可以想到将每种颜色随机映射到\(1\)到\(m\)中,这样子得出来的答案不会更优,而当答案选择的\(m\)种颜色恰好......
  • 20240924 模拟赛 T4 题解
    Description这是一道交互题。有一棵\(n\)个节点的树,现在要求你通过若干次询问得到这棵树的每一条边连接哪两个点。每次询问你需要指定\(n\)个整数\(d_1,d_2,\ldots,d_n\),满足\(-1\leqd_i\leqn\),其中\(1\leqi\leqn\)。每次询问交互库会返回给你一个长度为\(n\)的......
  • P4780 Phi的反函数 题解
    因为\(\varphi(x)\)的值只与\(x\)的不同质因子有关,又因为\(2^{31}\)之内的数的质因子个数不超过\(10\),所以容易枚举\(10\)个位置上填入的质因子打出朴素的暴力,简单剪枝后得到\(20\)分。注意需要先判掉\(x=n+1\)的情况。考虑优化:因为\(\varphi\)的值只与质因......