[题解] XOR Problem
题目大意
对于一个整数序列 \(a_{0...5}\),我们定义它的价值为:
\(f(a)=max(|a_0-a_3|,|a_1-a_4|,|a_2-a_5|)\oplus a_0 \oplus a_1 \oplus a_2 \oplus a_3 \oplus a_4 \oplus a_5\)
其中 \(\oplus\) 是异或操作。
现在给定序列 \(b_{0...5}\),你需要求对于所有满足 \(\forall i,0\leq a_i\leq b_i\) 的序列 \(a\) 的 \(f(a)\) 之和。
由于答案可能很大,你只需要输出答案对 \(2^{64}\) 取模后的值。
对于所有数据,有 \(0\leq b_i\leq 30000\)
时间限制:3 s
空间限制:512 MB
解题思路
是个不太难的题,然而我不会最后一档分。
考场做法是 \(f_{i,j}\) 表示 \(\max\) 不大于 \(i\),\(6\) 个数的异或值为 \(j\) 的方案数。
转移前缀和优化一下,再用奇怪的技巧加个 fwt 就可以有 62pts 了。
考虑如何把都是 \(O(b^2)\) 的时空复杂度降下去,一个套路的做法是把异或值每一位拆开计算。
\(f_{i,j,0/1}\) 表示 \(\max\) 不大于 \(i\),第 \(j\) 位为 \(0/1\) 的方案数,对于每一对分开求,再用 \(f\) dp 就不难了。
那 \(f\) 怎么求 ? 想到差一定是可以卷积的 (将数组翻转),把每一组,每一位,每一种 \(0/1\) 情况分开卷。
接下来的 dp 就和之前的暴力 dp 差不多了。
#include <bits/stdc++.h>
using namespace std;
const int B(30005), BIT(16);
int b[6];
int f[3][BIT][B][2];
inline void read(int &x ){
x = 0; int f = 1, c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)) x = x * 10 + c - 48, c = getchar();
x *= f;
}
namespace prep{
const int mod(998244353), G(3), Gi(332748118);
int n;
int a[1 << 16], b[1 << 16], c[1 << 16], rev[1 << 16];
inline void MOD(int &x){ x = x + ((x >> 31) & mod); }
inline int qpow(int x, int a){
int sum = 1; while(a){
if(a & 1) sum = 1LL * sum * x % mod;
x = 1LL * x * x % mod, a >>= 1;
} return sum;
}
void init(int len){
n = 1; while(n < len) n <<= 1;
for(int i(0); i < n; ++i) rev[i] = (rev[i >> 1] >> 1) | (i & 1) * (n >> 1);
}
void NTT(int *a, int n, int op){
int g = op == 1 ? G : Gi, inv = qpow(n, mod - 2);
for(int i(0); i < n; ++i) if(i < rev[i]) swap(a[i], a[rev[i]]);
for(int len(2), hf(1); len <= n; len <<= 1, hf <<= 1){
int wn = qpow(g, (mod - 1) / len);
for(int bs(0); bs < n; bs += len){
int w = 1;
for(int p(0); p < hf; ++p, w = 1LL * w * wn % mod){
int x = a[bs + p], y = 1LL * w * a[bs + hf + p] % mod;
MOD(a[bs + p] = x + y - mod);
MOD(a[bs + hf + p] = x - y);
}
}
}
if(op == -1) for(int i(0); i < n; ++i) a[i] = 1LL * a[i] * inv % mod;
}
void work(int t, int bit, int la, int lb, int x, int y){
memset(a, 0, sizeof a);
memset(b, 0, sizeof b);
memset(c, 0, sizeof c);
/* 将这一位符合枚举要求的取出来卷积 */
for(int i(0); i <= la; ++i) a[i] = ((i >> bit) & 1) == x;
for(int i(0); i <= lb; ++i) b[i] = ((i >> bit) & 1) == y;
/* 因为差是定值所以翻转一下 */
reverse(b, b + lb + 1);
init(la + lb + 2);
NTT(a, n, 1), NTT(b, n, 1);
for(int i(0); i < n; ++i) c[i] = 1LL * a[i] * b[i] % mod;
NTT(c, n, -1);
for(int i(0); i <= la; ++i) MOD(f[t][bit][i][x ^ y] += c[i + lb] - mod);
for(int i(0); i <= lb; ++i) MOD(f[t][bit][lb - i][x ^ y] += c[i] - mod);
}
void calc(int t, int bit, int la, int lb){
for(int x(0); x <= 1; ++x)
for(int y(0); y <= 1; ++y)
work(t, bit, la, lb, x, y);
/* 两数相等的时候算重了一次 */
f[t][bit][0][0] = 1LL * f[t][bit][0][0] * qpow(2, mod - 2) % mod;
f[t][bit][0][1] = 1LL * f[t][bit][0][1] * qpow(2, mod - 2) % mod;
}
}
namespace DP{
#define ULL unsigned long long
ULL ans, pre[4][B][2], dp[4][B][2];
void solve(int bit){
memset(dp, 0, sizeof(dp));
memset(pre, 0, sizeof(dp));
for(int t(1); t <= 3; ++t)
for(int i(0); i < B; ++i)
for(int j(0); j <= 1; ++j)
pre[t][i][j] = f[t - 1][bit][i][j] + (i ? pre[t][i - 1][j] : 0);
for(int j(0); j < B; ++j) dp[0][j][0] = 1;
for(int i(1); i <= 3; ++i)
for(int j(0); j < B; ++j){
for(int x(0); x <= 1; ++x)
for(int y(0); y <= 1; ++y)
dp[i][j][x ^ y] += dp[i - 1][j][x] * pre[i][j][y];
}
for(int i(B - 1); i; --i)
for(int j(0); j <= 1; ++j)
dp[3][i][j] -= dp[3][i - 1][j];
for(int i(0); i < B; ++i) for(int j(0); j <= 1; ++j)
if(((i >> bit) & 1) ^ j) ans += dp[3][i][j] * (1ULL << bit);
}
}
int main(){
// freopen("C.in", "r", stdin);
// freopen("C.out", "w", stdout);
for(int i(0); i < 6; ++i) read(b[i]);
for(int i(0); i < 16; ++i)
for(int j(0); j < 3; ++j)
prep :: calc(j, i, b[j], b[j + 3]);
for(int i(0); i < 16; ++i) DP :: solve(i);
cout << DP :: ans << endl;
return 0;
}
[题解] XOR Problem的更多相关文章
- Codeforces Round #525 (Div. 2)D. Ehab and another another xor problem
D. Ehab and another another xor problem 题目链接:https://codeforces.com/contest/1088/problem/D Descripti ...
- 2014 百度之星 1003 题解 Xor Sum
Xor Sum Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包括了N个正整数,随后 Prometheu ...
- codeforces#1157D. Ehab and the Expected XOR Problem(构造)
题目链接: http://codeforces.com/contest/1174/problem/D 题意: 构造一个序列,满足以下条件 他的所有子段的异或值不等于$x$ $1 \le a_i< ...
- 【CF1174D】 Ehab and the Expected XOR Problem - 构造
题面 Given two integers \(n\) and \(x\), construct an array that satisfies the following conditions: · ...
- cf1088D Ehab and another another xor problem (构造)
题意:有两数a,b,每次你可以给定c,d询问a xor c和b xor d的大小关系,最多询问62次($a,b<=2^{30}$),问a和b 考虑从高位往低位做,正在做第i位,已经知道了a和b的 ...
- CF D. Ehab and the Expected XOR Problem 贪心+位运算
题中只有两个条件:任意区间异或值不等于0或m. 如果只考虑区间异或值不等于 0,则任意两个前缀异或值不能相等. 而除了不能相等之外,还需保证不能出现任意两个前缀异或值不等于m. 即 $xor[i]$^ ...
- Codeforces Round #525 (Div. 2) D. Ehab and another another xor problem(待完成)
参考资料: [1]:https://blog.csdn.net/weixin_43790474/article/details/84815383 [2]:http://www.cnblogs.com/ ...
- Codeforces.1088D.Ehab and another another xor problem(交互 思路)
题目链接 边颓边写了半上午A掉啦233(本来就是被无数人过掉的好吗→_→) 首先可以\(Query\)一次得到\(a,b\)的大小关系(\(c=d=0\)). 然后发现我们是可以逐位比较出\(a,b\ ...
- cf1088D. Ehab and another another xor problem(思维)
题意 题目链接 系统中有两个数\((a, b)\),请使用\(62\)以内次询问来确定出\((a, b)\) 每次可以询问两个数\((c, d)\) 若\(a \oplus c > b \opl ...
随机推荐
- 你如何理解 Spring Boot 中的 Starters?
Starters可以理解为启动器,它包含了一系列可以集成到应用里面的依赖包,你可以一站式集成 Spring 及其他技术,而不需要到处找示例代码和依赖包.如你想使用 Spring JPA 访问数据库,只 ...
- 使用Spring框架的好处是什么?
轻量:Spring 是轻量的,基本的版本大约2MB. 控制反转:Spring通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们. 面向切面的编程(AOP):Spring支持 ...
- Python使用pip安装No matching distribution found for PyYaml==5.3.1
ERROR: Command errored out with exit status 1: command: /usr/local/dmahz/p_book_data/bin/python3.9 - ...
- 解释基于XML Schema方式的切面实现?
在这种情况下,切面由常规类以及基于XML的配置实现.
- git-learningmeiy
什么是版本控制-版本迭代: 版本控制(Revision control)是一种在开发的过程中用于管理我们对文件.目录或工程等内容的修改历史,方便查看更改历史记录,备份以便恢复以前的版本的软件工程技术. ...
- 什么是通知Advice?
特定 JoinPoint 处的 Aspect 所采取的动作称为 Advice.Spring AOP 使用一个 Advice 作为拦截器,在 JoinPoint "周围"维护一系列的 ...
- ES6-11学习笔记--扩展运算符与rest参数
1.符号都是使用:... 2.扩展运算符:把数组或者类数组展开成用逗号隔开的值 3.rest参数:把逗号隔开的值组合成一个数组 扩展运算符: function foo(a, b, c) { con ...
- Python计算身体质量指数BMI
使用Python计算身体质量指数BMI 运行结果如下: 源代码: 1 ''' 2 3. 利用函数思想,将"身体质量指数BMI"源程序封装成为一个函数并调用. 3 :param he ...
- 93. 复原 IP 地址
做题思路or感想 这种字符串切割的问题都可以用回溯法来解决 递归三部曲: 递归参数 因为要切割字符串,所以要用一个startIndex来控制子串的开头位置,即是会切割出一个范围是[startIndex ...
- Linux shell中2>&1的含义解释
https://blog.csdn.net/zhaominpro/article/details/82630528