题目
定义一个非负整数序列的舒适度为其所有子序列上元素的异或之和。
让你知道原序列长度为N,并且给你一些连续片段的位或值。
让你求原序列的异或之和。
题解思路
参考博客
考虑每一位对答案的贡献。
位d的子序列肯定得选奇数个1才能得出这个值2^d。
但是肯定是N个01组成的。
我们从1中选奇数个,0中的任意选择不会影响答案。
再由参考博客中大佬的证明
所以这个位的贡献就是2^d * 2 ^n-1 次方。(只有2的n-1次方的组成能得出他的值)前提是有1
这样我们积累有1的每一位即可。
大佬用了位或运算来积累出每一个位数的2^d 然后直接乘 2 ^n-1次方 。
属实巧妙。
AC代码
#include <bits/stdc++.h>
//#include <unordered_map>
//priority_queue
#define PII pair<int,int>
#define ll long long
using namespace std;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7 ;
const int N = 200100;
int a[N] ;
long long ksm(long long di , long long mi )
{
long long res = 1 ;
while (mi)
{
if (mi&1)
res = res * di %mod ;
mi >>= 1 ;
di = di * di %mod ;
}
return res ;
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int T ;
cin >> T ;
long long ans = 0 ;
while ( T-- )
{
int n , m ;
cin >> n >> m ;
ans = 0 ;
for (int i = 1 ; i <= m ; i++ )
{
int t1 , t2 , t3 ;
cin >> t1 >> t2 >> t3 ;
ans |= t3 ;
}
ans = ans*ksm(2,n-1)%mod ;
cout << ans <<"\n" ;
}
return 0 ;
}