H - ZYB loves Xor I HDU - 5269

【 题目意思 】:
给你一个长度为n的序列,选择其中两个元素(a b 和 b a 是两种选择) 将他们异或,求异或后的lowbit的和。
【 思路 】:
一个数的lowbit为,第一个不为0的数前有k个0,则为2^k 。
可以看到 lowbit 是二进制从右往左找第一个1的位置 ,(是从小往后找)。
那么异或之后值为1 ,就是在这一位上,原数组中的两个数 同时存在0 和 1。
所以只要从低位开始建字典树,当字典树的分叉同是有0和1 时 , 就是当前的lowbit。将这个值 乘以 分别存储的数的个数 就是答案。
【题解】 :
#include <bits/stdc++.h> #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <string> #include <vector> #include <stack> #include <bitset> #include <cstdlib> #include <cmath> #include <set> #define ms(a, b) memset(a,b,sizeof(a)) #define fast ios::sync_with_stdio(false); cin.tie(0); cout.tie(0) #define ll long long #define ull unsigned long long #define rep(i, a, b) for(ll i=a;i<=b;i++) #define lep(i, a, b) for(ll i=a;i>=b;i--) #define endl '\n' #define pii pair<int, int> #define pll pair<ll, ll> #define vi vector<ll> #define vpi vector<pii> #define vpl vector<pll> #define mi map<ll,ll> #define all(a) (a).begin(),(a).end() #define gcd __gcd #define pb push_back #define mp make_pair #define lb lower_bound #define ub upper_bound #define ff first #define ss second #define test4(x, y, z, a) cout<<"x is "<<x<<" y is "<<y<<" z is "<<z<<" a is "<<a<<endl; #define test3(x, y, z) cout<<"x is "<<x<<" y is "<<y<<" z is "<<z<<endl; #define test2(x, y) cout<<"x is "<<x<<" y is "<<y<<endl; #define test1(x) cout<<"x is "<<x<<endl; using namespace std; const int N = 1e5 + 10 ; const int maxx = 0x3f3f3f ; const int mod = 998244353 ; const int minn = -0x3f3f3f ; const int M = 2 * N ; ll T, n, m ; ll a[N] , Case ; ll ba[32] ; ll ans ; ll son[ N*35 ][ 2 ],idx,cnt[ N*35 ] ; void insert(ll n) { int p = 0 ; for ( int i =0 ;i<=30 ; i++ ){ int u = (n>>i) & 1 ; if ( !son[p][u] ){ son[p][u] = ++ idx ; son[idx][0] = son[idx][1] = 0 ; // 将字典树清空的办法 。 将新建的点的子节点全部变为0 cnt[idx] = 0 ; } p = son[p][u] ; cnt[ p ] ++ ; } } void dfs(int g,int deep ){ int l = son[g][0],r = son[g][1] ; if ( cnt[l]==0 && cnt[r]==0 ) return ; if ( r && l ){ ans = ( ( cnt[l]*cnt[r]*ba[deep]%mod ) + ans )%mod; dfs( l , deep+1 ); dfs( r , deep+1 ); }else if ( l ){ dfs( l ,deep+1 ); }else { dfs( r ,deep + 1 ); } } void solve() { cin>>n; ans = 0; idx = 0 ; son[0][0] = son[0][1] = 0 ; rep(i,1,n){ cin>>a[i]; insert(a[i]); } dfs(0,0); ans = ans*2 % mod; // printf("Case #%d: %d\n",Case,ans); cout<<"Case #"<<Case<<": "<<ans<<endl; } int main() { fast; ba[0] = 1; rep(i,1,30) ba[i] = ba[i-1] * 2 ; cin >> T ; Case = 1 ; while ( T-- ) { solve(); Case ++; } return 0; }

浙公网安备 33010602011771号