这个题实在太巧了
给你一个数组的元素个数,给出若干个区间的或和,问任意一个合法的原序列的所有子序列的区间异或和是多少
-
或的特点是二进制位只要有一个1,结果的对应位置就是1,可以想一下,给出这若干个区间信息,想要还原数组基本不太可能,而且就算是还原出了原来的数组,我们又怎么算这所有子序列的异或和呢?这个思路不靠谱
-
单独考虑某一位上的数字,如果这个数字在给出的区间范围内没有体现,那它就不会出现在答案中;否则要考虑子序列中该位对应的数出现奇数次和偶数次这两种情况,如果是偶数次,它对答案的贡献也是0;如果是奇数次,那么这个结论是包含第iii位的子序列个数是2n−12^{n-1}2n−1
-
知道这个结论以后,因为每个位之间是并列关系,所以我们分别考虑每一位然后加一起就是答案,比如说现在给我们l,r,xl,r,xl,r,x,假设都是对于某一位的,举一些例子a1∣a2∣a3=x1a3∣a4∣a5∣a6=x2a8∣a9∣a10=x3a_1|a_2|a_3=x_1 \\a_3|a_4|a_5|a_6=x_2\\a_8|a_9|a_{10}=x_3a1∣a2∣a3=x1a3∣a4∣a5∣a6=x2a8∣a9∣a10=x3
-
上面例子随便举的,那我们合并一下,就可以得到a1∣a2∣a3∣a4∣a5∣a6∣a8∣a9∣a10=x1∣x2∣x3a_1|a_2|a_3|a_4|a_5|a_6|a_8|a_9|a_{10}=x_1|x_2|x_3a1∣a2∣a3∣a4∣a5∣a6∣a8∣a9∣a10=x1∣x2∣x3,那么我们给这些数的这一位都标上一样的数字,如果右侧是0,那么全标0,否则全标1,那么这里面0的情况对答案的贡献是0,不用管,所以答案就是x×2n−1x\times2^{n-1}x×2n−1
-
感觉他们能秒了这个题肯定是早就知道这个结论
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MOD = 1e9 + 7;
ll fastpow(ll base, ll power, ll mod){
ll ans = 1;
while(power){
if(power & 1) ans = ans * base % mod;
base = base * base % mod;
power >>= 1;
}
return ans;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while(t--){
ll l, r, x;
int n, m;
cin >> n >> m;
ll ans = 0;
for(int i=0;i<m;i++){
cin >> l >> r >> x;
ans |= x;
}
cout << ans * fastpow(2ll, n - 1, MOD) % MOD << '\n';
}
return 0;
}
- 按照官方题解思路对此结论进行证明,把第iii位为0的标号划分为集合AAA,把第iii位为1的标号划分为集合BBB, 因为x⊕0=xx\oplus0=xx⊕0=x,所以无论如何选择AAA中元素都不会影响答案,所以这一部分数量是2∣A∣2^{|A|}2∣A∣;对于集合BBB,因为都是1,所以只需要考虑异或出来是1的组合即可,这部分的数量为(∣B∣1)+(∣B∣3)+...+(∣B∣∣B∣−k)=2∣B∣−1\begin{pmatrix} |B| \\ 1 \end{pmatrix}+\begin{pmatrix} |B|\\3\end{pmatrix}+...+\begin{pmatrix} |B|\\|B|-k\end{pmatrix}=2^{|B|-1}(∣B∣1)+(∣B∣3)+...+(∣B∣∣B∣−k)=2∣B∣−1,当BBB为偶数时kkk为111,当BBB为奇数时,kkk为000
- 把AAA和BBB组合在一起,答案就是2∣A∣×2∣B∣−1=2n−12^{|A|}\times2^{|B|-1}=2^{n-1}2∣A∣×2∣B∣−1=2n−1
备注 (1−x)n=Cn0(−1)0x0+Cn1(−1)1x1+...+Cnn(−1)nxn(1-x)^n=C_n^0(-1)^0x^0+C_n^1(-1)^1x^1+...+C_n^n(-1)^nx^n(1−x)n=Cn0(−1)0x0+Cn1(−1)1x1+...+Cnn(−1)nxn
令x=1x=1x=1得到
Cn0+Cn2+...+Cnn−(n&1)=Cn1+Cn3+...+Cnn−(!(n&1))C_n^0+C_n^2+...+C_n^{n-(n\&1)}=C_n^1+C_n^3+...+C_n^{n-(!(n\&1))}Cn0+Cn2+...+Cnn−(n&1)=Cn1+Cn3+...+Cnn−(!(n&1))