World Tour Finals 2022 Day2 E: Adjacent Xor Game

Rainbow_qwq發表於2024-06-17

考慮從高到低位做,不斷貪心的一個過程。即假設把當前所有數 \(a_i\) 看成 \(\lfloor \frac{a_i}{2^d} \rfloor\),有當前最優答案 \(ans_d\);現在把所有數看成 \(\lfloor \frac{a_i}{2^{d-1}} \rfloor\),推出下一步的答案 \(ans_{d-1}\)

假設 \(/2^d\) 時,每一步 xor 完的序列是 \(a_1,a_2,..,a_m\),其中 \(a_i < a_{i+1}\)\(a_m=ans_d\)(這裡忽略了所有 \(=0\) 的數)。從 \(d\to d-1\) 時,現在每個 xor 的數會變為 \(2x\)\(2x+1\),並且會加入一堆 \(1\)

如果沒有新加入的 1,那麼顯然 \(ans_{d-1} = ans_d\times 2\)。發現新加入的一堆 1 對序列很有影響,因為它們只能被插在“空位”裡,如果“空位”不足就會不得不增加 \(ans_{d-1}\)

據此可以寫出一份暴力,計算一個陣列 \(a\) 的答案:

int wk(vi o){
	n=o.size();For(i,1,n)a[i]=o[i-1],vis[i]=0;
	int now=0,res=0;
	Rep(i,30,0){
		int cnt=0,cnt2=now;
		For(j,1,n){
			if(!vis[j] && (a[j]>>i&1)) ++cnt,vis[j]=1;
			else if(vis[j] && (a[j]>>i&1)) ++cnt2;
		}
		if(cnt<=cnt2) now+=(cnt2-cnt),res=res*2;
		else if(cnt<=cnt2+1) res=res*2+1;
		else {
			cnt-=(cnt2+1);
			now+=cnt;
			res+=cnt;
			res*=2;
			res+=1;
		}
	//	cout<<"res "<<i<<" "<<res<<" "<<now<<"\n";
	}
	return res;
}

相關文章