首页 > 其他分享 >Atcoder ARC165D Xor Sum 5

Atcoder ARC165D Xor Sum 5

时间:2024-03-18 21:55:39浏览次数:21  
标签:Atcoder le Xor int Sum binom operatorname 考虑 bmod

考虑到这个最终的答案是 \(\oplus\),所以只需要考虑每种排列出现的次数的奇偶,如果为奇再计算贡献即可。

考虑什么情况下出现次数为奇。
令每个数出现的个数为 \(c_{1\sim n}\),方案数即为 \(\dbinom{k}{c_1, c_2, \cdots, c_n} = \prod_{i = 1}^n \dbinom{k - \sum\limits_{j = 1}^{i - 1} c_j}{c_i}\)。
如果 \(\bmod 2 = 1\) 那么就说明 \(\dbinom{k - \sum\limits_{j = 1}^{i - 1} c_j}{c_i}\bmod 2 = 1(1\le i\le n)\),由 \(\text{Lucas}\) 定理可以得到二进制意义下 \(c_i\subseteq (k - \sum\limits_{j = 1}^{i - 1} c_j)\)。
证明就是考虑拆二进制位,因为 \(\binom{0}{0} = \binom{1}{1} = \binom{1}{0} = 1, \binom{0}{1} = 0\),所以如果 \(\bmod 2 = 1\) 需要每一位都满足是前 \(3\) 种,也就是对应的子集关系。

那么整理一下就有 \(c_i\operatorname{bitand}c_j = 0(1\le i < j\le n), c_1\operatorname{bitor} c_2 \operatorname{bitor}\cdots \operatorname{bitor} c_n = k\)。

对于答案,可以考虑拆位,对每一位依次来考虑为 \(0\) 还是 \(1\)。

因为能发现值域 \(V\le 1000\),考虑直接 \(\text{DP}\),设 \(f_{w, i}\) 为只考虑到第 \(w\) 位,到这一位的和为 \(j\) 的方案数为奇还是偶。
那么转移分为两种,如果下一位 \(k\) 为 \(0\),就选不了数,就直接折半由 \(i\) 转移到 \(\lfloor\frac{i}{2}\rfloor\)。
否则这一位需要选一个 \(a_j\) 出来,就会转移到 \(\lfloor\frac{i}{2}\rfloor + a_j\)。

然后考虑算这一位是不是 \(1\)。
首先因为只考虑了前 \(w\) 位,若还有 \(c\) 位没考虑,那么方案数应该乘上 \(n^{c}\),当 \(n\bmod 2 = 0\land c > 0\) 时肯定为偶,直接跳过。
否则考虑找出 \(f_{w, i} = 1\) 的 \(i\),把这些 \(\oplus\) 起来,如果最低位为 \(1\) 就说明第 \(w\) 位为 \(1\)。

时间复杂度 \(O(nV\log k)\),\(V\) 为值域。

代码
#include<bits/stdc++.h>
using i64 = long long;
const int maxn = 1e3 + 10;
int n;
int a[maxn];
int is1[52];
int f[52][maxn * 2];
int main() {
    i64 k; scanf("%d%lld", &n, &k);
    for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
    for (int i = 0; i < 50; i++) is1[i] = (k >> i & 1ll);
    int c = 0;
    for (int i = 0; i < 50; i++) c += is1[i];
    i64 ans = 0;
    if (is1[0]) {
        for (int i = 1; i <= n; i++) f[0][a[i]] ^= 1;
    } else f[0][0] = 1;
    for (int i = 0; i < 50; i++) {
        if (is1[i]) c--;
        if ((n & 1) || ! c) {
            int t = 0;
            for (int j = 0; j <= 2000; j++) f[i][j] && (t ^= j);
            if (t & 1) ans |= 1ll << i;
        }
        if (! is1[i + 1]) {
            for (int j = 0; j <= 2000; j++) f[i + 1][j >> 1] ^= f[i][j];
        } else {
            for (int j = 0; j <= 2000; j++) for (int p = 1; p <= n; p++) f[i + 1][(j >> 1) + a[p]] ^= f[i][j];
        }
    }
    printf("%lld\n", ans);
    return 0;
}

标签:Atcoder,le,Xor,int,Sum,binom,operatorname,考虑,bmod
From: https://www.cnblogs.com/rizynvu/p/18081548

相关文章

  • Monoxer Programming Contest 2024(AtCoder Beginner Contest 345)
    MonoxerProgrammingContest2024(AtCoderBeginnerContest345)\(A\)Leftrightarrow\(100pts\)按照题意模拟即可。点击查看代码intmain(){strings;inta=0,b=0,c=0,i;cin>>s;for(i=0;i<s.size();i++){a+=(s[i]=='<&#......
  • AtCoder-abc345_f题解
    题意简述给定一个无向图。你要在其中选出一些边,使得选出的边所构成的图中,度数为奇数的点有\(K\)个。如果可以,输出选了哪些边,否则输出-1。思路首先在选一条边时,边两端点度数的奇偶性一定都会改变,即要么都变为奇数,要么两个点的奇偶性交换过来,要么都变为偶数。这三种情况时满足......
  • AtCoder Beginner Contest 345
    是这样的,C的longlong只开了ans没开全局,AC12WA12,调了一个小时,在赛后1min发现了该错误。没开longlong见祖宗,望周知;这是C的码,简单的小题一只,可怜的longlong。#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;strings;intn,f,ans;map<char......
  • XOR Break — Solo Version
    题意思路最多两步解决1.一步:只要满足((n^m)<n)即可一步,只要在第一个mi=1的地方n也有1无论如何都可以随便改n得到m2.无解的情况:只要在第一个mi=1的时候n(i)->n(最高位-1)没有1出现肯定无法解决3.二步:类似于10110->0000110110->10101->00001只需......
  • LeetCode网 - 0001:Two Sum
    Givenanarrayofintegersnums andanintegertarget,returnindicesofthetwonumberssuchthattheyadduptotarget.Youmayassumethateachinputwouldhaveexactlyonesolution,andyoumaynotusethesameelementtwice.Youcanreturntheanswer......
  • 维修住友注塑机 Sumitomo SE50D 工业液晶屏 SE50S工业电脑显示屏
    Sumitomo(SHI)Demag的NC5plus控制器是一款易于使用的控制器,可帮助成型商实现卓越的注塑成型精度。该控制器作为用户和注塑机之间的通信接口发挥着关键作用。只有通过控制才能访问机器的全部性能属性,从而以各种方式帮助最大限度地提高生产效率。NC5+优点易于使用并快速......
  • AtCoder Grand Contest 022 E Median Replace
    洛谷传送门AtCoder传送门考虑对于一个确定的串怎么判断合法性。容易发现删到某个时刻若\(1\)的个数大于\(0\)的个数了,因为我们肯定不会蠢到在不是全\(1\)的时候删\(111\),所以\(c_1-c_0\)在不是全\(1\)的时候至少是不会变小的。所以我们的目标就是让\(c_1-c_0......
  • AtCoder Beginner Contest 344 A-G 题解
    AtCoderBeginnerContest344A-SpoilerQuestion删除两个|之间的字符Solution按照题意模拟即可Code#include<bits/stdc++.h>usingnamespacestd;intmain(){strings;cin>>s;stringp1,p2;for(inti=0;i<s.size();i++){......
  • Toyota Programming Contest 2024#3(AtCoder Beginner Contest 344)
    C先预处理出三个数组能拼出的数,存放到map中。查询的时候只需要看这个数是否出现在map里即可。时间复杂度\(O(n^3\logv+Q\logv)\),\(n\leq100\),\(\logv\)是map的时间复杂度。#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintN=3e......
  • 载谭 Binomial Sum 学习笔记
    对于微分有限的生成函数\(F(x)\),有一个生成函数\(G(x)\),以及数列\(a\),如果对于\(0\lek\len\),我们已知\(\displaystyle\sum_{i=0}^na_i[x^i]G(x)^k\),那么我们能够在\(\Theta(n)\)的时间复杂度内求出\(\displaystyle\sum_{i=0}^na_i[x^i]F(G(x))\)。设\(c=[x^0]......