题解:洛谷P10128 「Daily OI Round 3」Xor Graph

题目链接:洛谷P10128 「Daily OI Round 3」Xor Graph

首先,观察到如果 \(x \operatorname{xor} y = 2^k,k \in [1,n)\),那么 \(x\)\(y\) 的二进制位上有且仅有一位不同。

其次,还要保证 \(x > y\),那么只有当 \(y\) 是将 \(x\) 的某二进制位 \(1\) 变为 \(0\) 时,才可以使两个性质都成立。

考虑求 \(\displaystyle\sum_{i=1}^{2^n}\sum_{j=1,j \neq i}^{2^n}f(i,j)\),如果枚举点对,那么复杂度一定超,于是我们枚举每种长度的线段的个数,动态考虑该问题,每走一步,就将二进制位上的某个 \(1\) 变为 \(0\),直到二进制位上只有一个 \(1\) 为止。

就可以发现,从一个数出发存在长度为 \(n\) 的路径,当且仅当这个数二进制位上 \(1\) 的个数大于 \(n\)

现在有 \(2^n\) 个点,因此每个数都可以表示成一个 \(n\) 位二进制数,可以先枚举这个数的二进制位上有多少个 \(1\),再钦定哪几个位上是 \(1\),最后确定删几个 \(1\) 以及删 \(1\) 的顺序。

现在,答案就变成了求 \(\displaystyle\sum_{i=2}^n \binom ni \sum_{j=1}^{i-1} i^{\underline{j}}\)

无脑大力推式子:原式

\(\begin{aligned} &= \displaystyle\sum_{i=2}^n \sum_{j=1}^{i-1} \binom ni i^{\underline{j}} \\&= \sum_{i=2}^n \sum_{j=1}^{i-1} \binom ni \binom ij j! \\&= \sum_{i=2}^n \sum_{j=1}^{i-1} \binom nj \binom{n - j}{i - j} j! \\&= \sum_{j=1}^{n - 1} \sum_{i=j+1}^{n} \binom nj \binom{n - j}{i - j} j! \\&= \sum_{j=1}^{n - 1} \binom nj j! \sum_{i=j+1}^{n} \binom{n - j}{i - j}\\ &= \sum_{j=1}^{n - 1} \binom nj j! (2^{n-j}-1) \end{aligned}\)

已经 \(O(n)\) 不能再优化了,但这道题的数据十分可爱极限,导致我们只能递推预处理qwq。

将括号拆开,得:\(\displaystyle\sum_{j=1}^{n - 1} \binom nj j! 2^{n-j} - \sum_{j=1}^{n - 1} \binom nj j!\)

现在两边都可以预处理,那这道题就做完了。

代码(其实不长):

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e7 + 9, mod = 998244353;
int ans1[N], ans2[N], mi;
int t;
signed main(){
	ans1[1] = ans2[1] = 0;
	ans1[2] = 2, ans2[2] = 4;
	mi = 4;
	for(int i = 3; i <= 1e7; i++){
		ans1[i] = (ans1[i - 1] * i + i) % mod;//减号左边递推 
		ans2[i] = (ans2[i - 1] * i + i * mi) % mod;//减号右边递推 
		mi = mi * 2 % mod;
	}
	scanf("%d",&t);
	while(t--){
		int x;
		scanf("%d",&x);
		printf("%lld\n",(ans2[x] - ans1[x] + mod) % mod);
	}
	return 0;
} 
posted @ 2024-09-20 17:01  Orange_new  阅读(27)  评论(0)    收藏  举报