CF1054D-Changing Array【贪心】
生活随笔
收集整理的這篇文章主要介紹了
CF1054D-Changing Array【贪心】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正題
題目鏈接:https://www.luogu.com.cn/problem/CF1054D
題目大意
一個長度為nnn的序列,每個數小于2k2^k2k,可以選擇一些數xorxorxor上2k?12^k-12k?1。要求使得滿足alxoral+1xor...xorar=0a_l\ xor\ a_{l+1}\ xor...xor\ a_r=0al??xor?al+1??xor...xor?ar?=0的區間個數最少。
解題思路
首先做前綴xorxorxor,這樣就變成了al?1xorar=0a_{l-1}\ xor\ a_r=0al?1??xor?ar?=0的數量最少,也就算相同的對數最少。
若axor(2k?1)=ba\ xor\ (2^k-1)=ba?xor?(2k?1)=b或者a=ba=ba=b我們將它們視為同一類,它們可以相互轉換,對于每一類我們一半取大的,一半取小的即可。
時間復雜度O(nlog?n)O(n\log n)O(nlogn)
codecodecode
#include<cstdio> #include<cstring> #include<algorithm> #include<map> using namespace std; const int N=2e5+10; int n,k,a[N];long long ans; map<int,int> v; long long p(int x) {return 1ll*x*(x-1)/2;} int main() {scanf("%d%d",&n,&k);int ms=(1<<k)-1;v[0]++;for(int i=1;i<=n;i++){scanf("%d",&a[i]);a[i]^=a[i-1];if(ms-a[i]>a[i])v[a[i]]++;else v[ms-a[i]]++;}map<int,int>::iterator it=v.begin();ans=1ll*n*(n+1)/2;for(;it!=v.end();it++){int x=it->second;ans-=p(x/2)+p(x-x/2);}printf("%lld\n",ans);return 0; }總結
以上是生活随笔為你收集整理的CF1054D-Changing Array【贪心】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 不是ddos攻击应有的程序(不是ddos
- 下一篇: P3329-[ZJOI2011]最小割【