一年之後再看好歹是會雙log做法的84分的,雖然可能被卡常
首先顯然有 \(x\oplus y\le x+y\)。
對於一個最優的方案 \(S,x\) 你顯然如果不影響 $\oplus $ 部分的最值的話移走的最優的。
所以我們只會將會影響 $\oplus $ 部分最值的留在 \(S\)。
考慮二分答案 \(mid\),判斷有沒有 \(\ge mid\) 的方案。
則因為 \(x\oplus y\le x+y\),所以事實上有:
而那麼在滿足 \(x\ge mid-a_{\min}\) 的條件之下,如果不滿足 \(a_i\oplus x\ge mid\),則必然需要加入 \(S\),且儘可能少加入。
則可以得到存在合法方案的充要條件是:
考慮將 \(a_i\oplus x\) 與 \(mid\) 作比較,感覺 \(x\) 很容易貪心地填 \(1\)。
轉化物件,以 \(a_i\) 為主元。
感覺如果有 \(a_i\oplus x<mid\),那麼顯然可以數位DP劃分出 $\log $ 個區間,那麼就可以變成區間加,然後全域性最小值查詢了。
這樣就得到了 $3\log $ 做法
最佳化?
其實還是對應了 \(trie\) 上的點,所以可以變成 \(trie\) 上的單點加全域性 \(\min\) 維護。
感覺還是容易的,得到了 $2\log $ 做法。
然後我們需要一個字尾 min
,可以實現
考慮Trie的實現細節
其實是看 \(mid\) 的每一位和 \(x\) 當前的每一位,然後統一算所有走到這裡的 \(a\) 的貢獻,其實這個 \(a\) 應該是在子樹內部。
所以我們需要維護一個子樹內 \(b\) 的和。
-
\(bit(mid)=1\),則
取 \(x=1\) 相當於繼續遞迴左子樹,而左子樹可以直接加上右子樹的 \(b\) 了
取 \(x=0\) 相當於繼續遞迴右子樹,而右子樹可以直接加上左子樹的 \(b\) 了。
-
\(bit(mid)=0\),則
取 \(x=1\) 相當於繼續遞迴右子樹,左子樹已經解決
取 \(x=0\) 相當於繼續遞迴左子樹,右子樹已經解決
所以可以子樹內維護當前位置 \(mid\) 是 \(1\),更低位置全 \(0\) 在子樹內是否有解,也就是要求 \(x\ge mid-a_1\),所以我們維護有解的最大 \(x\)?
我們不妨設一個 \(sol(p,mid,dep,now,mna,sumb)\)
也就是當前劃分到的集合 \(S\) 裡的 \(mna\),當前節點是 \(p\),深度 \(dep\),當前得到的答案是 \(mid\),當前填的 \(x\) 是 \(now\),當前已經得到了 \(sumb\) 的加法標。
列舉當前 \(mid\) 和 \(now\) 怎麼取的 \(4\) 類情況討論即可
ll sol(int p,int dep,ll mid,ll now,ll mna,int sumb){
if(sumb>m)return 0;
if(dep<0)return mid;
ll res=0;
//mid=1,now=1,遞迴左子樹,算上右子樹b
//mid+=pw[d],now+=pw[d]
int lc=ch[p][0],rc=ch[p][1];
ll lmna=min(ma[rc],mna),rmna=min(ma[lc],mna);
if(pw[dep]+now+pw[dep]-1+lmna>=mid+pw[dep]){
res=max(res,sol(lc,dep-1,mid+pw[dep],now+pw[dep],lmna,sumb+sb[rc]));
}
//mid=1,now=0,遞迴右子樹,算上左子樹b
if(now+pw[dep]-1+rmna>=mid+pw[dep]){
res=max(res,sol(rc,dep-1,mid+pw[dep],now,rmna,sumb+sb[lc]));
}
if(res>0)return res;
//mid=0,now=1,遞迴右子樹,左子樹無貢獻,mna無需更新
if(pw[dep]-1+pw[dep]+now+mna>=mid){
res=max(res,sol(rc,dep-1,mid,now+pw[dep],mna,sumb));
}
if(pw[dep]-1+now+mna>=mid){
res=max(res,sol(lc,dep-1,mid,now,mna,sumb));
}
return res;
}
然後優先 \(mid\) 是 \(1\) 的解,大力遞迴就好了。我們每一層根據 \(mna+now\ge mid\) 來減枝,可以保證每次往下搜的時候只要能夠遞迴就可以得到解,所以每個點只會遞迴一次,複雜度 \(O(Tnk)\)
這貪心是真NB
這個題涉及到了很多技巧:
- 貪心將不會影響答案的東西移走,使最優方案更容易滿足邊界條件
- 整體與單體的視角轉化,\(\sum_{a_i\oplus x<mid}b_i\) 從列舉 \(x\) 單體——整體計算變成對於每個 \(a_i\) 的單體整體統計貢獻,有時候正難則反。
- 限制條件的解決形式,如 \(x\ge [mid-a_{\min},2^k-1]\) 不用再計算單 \(a_i\) 貢獻時考慮邊界,而是在貢獻完之後整體照邊界
- 位運算題目,二分答案往往可以被按位貪心討論簡化掉。