安吉D17 T1
778 字
4 分钟
安吉D17 T1
- 1安吉D19 T1
- 2安吉D19 T3
- 3安吉D20 模考12总结
- 4安吉D17 T3
- 5安吉D17 T4
- 6安吉D19 模考11总结
- 7安吉D15 A
- 8安吉D16 T4
- 9安吉D17 T1本文
- 10安吉D17 模考10总结
- 11安吉D16 T3
- 12安吉D16 模考9总结
- 13安吉D13 模考8总结
- 14安吉D13-T2
- 15安吉D13-T3
- 16安吉D12-T3
- 17安吉D11-B
- 18安吉D11-C
- 19安吉D11-D
- 20安吉D12 模考7总结
- 21安吉D12-T2
- 22安吉D11-A
- 23安吉D10 模考6总结
- 24安吉D10-T3
- 25安吉D10-T4
- 26安吉D8-E
- 27安吉D9-T4
- 28安吉D8-A
- 29安吉D8-B
- 30安吉D8-C
- 31安吉D8-D
- 32安吉D9 模考5总结
- 33安吉D9-T2
- 34安吉D9-T3
- 35安吉D6-T4
- 36安吉D4-G
- 37安吉D5-T2
- 38安吉D6 模考4总结
- 39安吉D6-T1
- 40安吉D6-T3
- 41安吉-开营测试 T4
- 42安吉D5 模考3总结
- 43安吉D5-T3
- 44安吉D4-A
- 45安吉D4-B
- 46安吉D4-C
- 47安吉D4:容斥原理
- 48安吉Day4-D
- 49安吉D3 模考2总结
- 50安吉D3-T1
- 51安吉D3-T2
- 52安吉D3-T4
- 53安吉D2 模考1总结
- 54安吉D2-T2
- 55安吉D1-G
- 56安吉D1-L
- 57安吉D2-T4
原题呈现
我们知道,按位异或具有位独立性,即位与位之间的运算是独立的,因此可以按位计算贡献.
对于子串贡献题,最常见的是使用 dp,定义 dp[i] 表示以第 个数结尾能够做出的贡献.由于异或具有位独立性,因此,对状态稍作修改,定义状态 dp[i][j] 表示只考虑每一个数的第 位,以第 个数为结尾的子串中异或和为 1 的数量.即若设 表示 的第 位,则 为 ,满足 的 的数量.
这样就可以开始 dp 了,对于每一位 ,初始状态为 ,接着,遍历每一个数,设遍历到第 个数,则:
- 若 ,
- 对于以 结尾且长度为 1 序列,其异或和为 0,故对答案没有贡献.
- 对于以 结尾且长度为 的序列,其异或和为不会发生改变,因此原来以 结尾,长度为 的序列异或了 0 之后值仍不变.因此,这种情况对答案的贡献就是以 结尾的序列中异或和为 1 的序列数量.
- 因此存在转移方程:.
- 若 ,
- 对于以 结尾且长度为 1 序列,其异或和为 1,对答案贡献为 1.
- 对于以 结尾且长度为 的序列,其异或和会改变,因此原来以 结尾,长度为 的序列异或了 1 之后原来是 1 的会变成 0,原来是 0 的会变成 1.因此,这种情况对答案的贡献就是以 结尾的序列中异或和为 0 的序列数量.使用总序列数量 ,减去为 1 的序列数量 即可.
- 因此存在转移方程:.
对于答案,我们需要统计以每一个数结尾的子串每一位的贡献,即:
可以写出标程.由于 只与 有关,故可以把 数组变成一个变量 ans 以达到节省空间的效果,以下标程实现了这个效果.
标程
#include <bits/stdc++.h>using namespace std;#define int long longconst int N = 2e6 + 100;int a[N], ans;
signed main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n; cin >> n; for (int i = 1; i <= n; i++) { cin >> a[i]; } for (int i = 0; i < 32; i++) { int now = (a[1] >> i) & 1; ans += now * (1 << i); for (int j = 2; j <= n; j++) { if (a[j] & (1 << i)) { now = j - 1 - now + 1; } ans += now * (1 << i); } } cout << ans; return 0;}文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!


