题解:P12147 【MX-X11-T1】「蓬莱人形 Round 1」仅此而已,就已经足够了
题意
给定 \(n,k\),求出 \(\sum_{x=0}^nx\oplus(x+2^k)\)。多测,\(1\leq T\leq 10^5,0\leq n<2^{29},0\leq k\leq 29\)。
题解
设 \(B=\lfloor\log_2(n)\rfloor\)。特判 \(k>B\),此时答案为 \(2^k(n+1)\)。
容易注意到 \(+2^k\) 不会影响到第 \(0\sim k-1\) 位,因此若每 \(2^k\) 个数分为一组,则组内的 \(f\) 值相同。形式化地:
\[f(t2^k)=f(t2^k+1)=\cdots=f((t+1)2^k-1)
\]
设 \(x=\left\lfloor\dfrac{n}{2^k}\right\rfloor\),最后会剩下形如
\[f(x2^k)=f(x2^k+1)=\cdots f(n)
\]
的余项,和为 \(f(n)\times((n\bmod{2^k})+1)\),我们将其累加到答案上。
接下来我们需要算出 \(2^k\sum\limits_{i=0}^{x-1}f(i2^k)\)。尝试进一步刻画 \(+2^k\) 带来的影响,可以发现,其实相当于找到第 \(k\) 位起最低的为 \(0\) 的位 \(p\),将 \([k,p]\) 位全部翻转,因此 \(f(x)=\sum\limits_{i=k}^p2^i\)。
于是我们只需要枚举 \(p\in[k,B]\),计算对应的 \(i2^k\) 的数量。设 \(g(p)=\sum\limits_{i=k}^{p-1}2^i\),我们相当于确定了
\[i2^k\equiv g(p)\pmod{2^{p+1}}\Leftrightarrow i\equiv \frac{g(p)}{2^k}\pmod{2^{p+1-k}}
\]
\(0\leq i\leq x-1\),解不等式可得方案数为 \(\left\lfloor\dfrac{x-1-\frac{g(p)}{2^k}}{2^{p+1-k}}\right\rfloor+1\)。
时间复杂度为 \(\mathcal{O}(T\log{n})\)。
代码
#include <iostream>
#include <cmath>
using namespace std;
#define lowbit(x) ((x) & -(x))
#define chk_min(x, v) (x) = min((x), (v))
#define chk_max(x, v) (x) = max((x), (v))
typedef long long ll;
typedef pair<int, int> pii;
ll t, n, k, x, s1, s2;
ll ans;
int main() {
ios::sync_with_stdio(0), cin.tie(0);
cin >> t;
while (t--) {
cin >> n >> k, x = n >> k, s1 = s2 = 0;
int b = log2(n);
if (k > b) cout << (ans = (1ll << k) * (n + 1)) << '\n';
else {
ans = (n ^ (n + (1 << k))) * ((n & ((1 << k) - 1)) + 1);
for (int i = k; i <= b; ++i) {
int c = (x - s2 - 1) >> (i - k + 1);
s1 += 1 << i, s2 += 1 << (i - k), ans += ((c + 1) * s1) << k;
}
cout << ans << '\n';
}
}
return 0;
}

浙公网安备 33010602011771号