Mail.Ru Cup 2018 Round 1 D
阿新 • • 發佈:2018-12-18
題意:
給定n個數的序列,每個數的二進位制數看作是k位的,你可以改變任意一個數,使得區間異或和不為零的個數最多,
改變的規則可以是把每個數跟 2^k - 1 進行異或
思路:
首先我們需要知道區間異或和可以有區間字首異或和得到,,即 a_i-j = sum_j ^ sum_(i-1);
還要知道這樣的一段區間,不論改變那個數,改變幾個,區間的異或和只有兩種可能; // 剛剛知道
這樣的話,我們就要使得字首異或和中相同的數的總的數量最少,
其實是個貪心,對於當前的數a_i 我們是否選擇改變,有兩種影響,就是他們字首和的值對後面的影響,我們要使得總數儘量小的話,那就讓前面出現的個數儘量少;
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e5 + 7; ll n, k; map<ll, ll> mp; int main() { scanf("%lld%lld", &n, &k); ll ans = n * (n + 1) / 2LL; ll pre = 0, max_ = (1<<k)-1; mp[0] = 1; for(int i = 1; i <= n; ++i) { ll x; scanf("%lld", &x); ll t1 = pre ^ x; ll t2 = t1 ^ max_; if(!mp.count(t1)) mp[t1] = 0; if(!mp.count(t2)) mp[t2] = 0; if(mp[t1] <= mp[t2]) { ans -= mp[t1]; mp[t1]++; pre = t1; } else { ans -= mp[t2]; mp[t2]++; pre = t2; } } printf("%lld\n", ans); return 0; }