CF1553H-XOR and Distance【dp】
正題
題目鏈接:https://www.luogu.com.cn/problem/CF1553H
題目大意
給出nnn個在[0,2n)[0,2^n)[0,2n)范圍內的數字序列aaa。
對于每個x∈[0,2n)x\in[0,2^n)x∈[0,2n)求
min?i≠j∣aixorx?ajxorx∣\min_{i\neq j}\ |a_i\ xor\ x-a_j\ xor\ x|i?=jmin??∣ai??xor?x?aj??xor?x∣
2≤n≤2k,1≤k≤192\leq n\leq 2^k,1\leq k\leq 192≤n≤2k,1≤k≤19
解題思路
一個很妙的想法,考慮一個數字aaa與xxx有最多只有前ddd位不同的情況,記答案為fx,df_{x,d}fx,d?。
考慮這個答案的性質,對于xxx找一個一個與它恰好第ddd位不同的yyy考慮轉移,首先顯然是從min{fx,d?1,fy,d?1}min\{f_{x,d-1},f_{y,d-1}\}min{fx,d?1?,fy,d?1?}處進行一個轉移(因為只多了第ddd位可以不同,而此時這兩種轉移就包括了兩個點集內的情況)。
但是還有一種轉移有可能是在xxx的集合和yyy的集合中各自選一個數字,我們可以各自找到兩個分別在x/yx/yx/y的集合中的數字aixorxa_i\ xor\ xai??xor?x最大并且ajxorya_j\ xor\ yaj??xor?y最小轉移到xxx即可。
考慮如何快速找這兩個數字,設mxx,d,mix,dmx_{x,d},mi_{x,d}mxx,d?,mix,d?表示上述所示情況下xxorax\ xor\ ax?xor?a的最大值/最小值,這兩個的轉移十分顯然。
mxx,d=max{mxx,d?1,mxy,d?1+2d}mx_{x,d}=max\{mx_{x,d-1},mx_{y,d-1}+2^d\}mxx,d?=max{mxx,d?1?,mxy,d?1?+2d}
mix,d=min{mix,d?1,miy,d?1+2d}mi_{x,d}=min\{mi_{x,d-1},mi_{y,d-1}+2^d\}mix,d?=min{mix,d?1?,miy,d?1?+2d}
時間復雜度:O(2kk)O(2^kk)O(2kk)
code
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=1<<19; int n,k,mx[N],mi[N],f[N]; int main() {scanf("%d%d",&n,&k);memset(mx,0xcf,sizeof(mx));memset(mi,0x3f,sizeof(mi));memset(f,0x3f,sizeof(f));for(int i=1,x;i<=n;i++){scanf("%d",&x);mx[x]=mi[x]=0;}int MS=(1<<k);for(int i=0;i<k;i++){for(int s=MS-1;s>=0;s--)if((s>>i)&1){int t=s^(1<<i);f[s]=f[t]=min(f[s],f[t]);f[s]=min(f[s],mi[t]+(1<<i)-mx[s]);f[t]=min(f[t],mi[s]+(1<<i)-mx[t]);int mxt=mx[t],mit=mi[t];int mxs=mx[s],mis=mi[s];mx[s]=max(mx[s],mxt+(1<<i));mi[s]=min(mi[s],mit+(1<<i));mx[t]=max(mx[t],mxs+(1<<i));mi[t]=min(mi[t],mis+(1<<i));}}for(int i=0;i<MS;i++)printf("%d ",f[i]);return 0; }總結
以上是生活随笔為你收集整理的CF1553H-XOR and Distance【dp】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微软必应聊天已无缝集成 Excel,可快
- 下一篇: CSP2021NOIP2021游记