2022-01-27 16:24阅读: 158评论: 0推荐: 0

Atcoder Beginner Contest 236 F Spices

F. Spices

题目大意

12n中选一些数出来,使得可以用这些数通过异或运算可以表示 12n中的任何数。选第 i个数的代价为 ai,最小化代价。

解题思路

肯定是线性基,我们贪心地从代价小的数开始插入线性基,能插就插,不能插就扔。这样最终代价是最小的。

至于证明,即插入四个数a,b代价依次增大,能插 a但我不插 a反而插 b的话,从最终结果考虑,我可以用b和其他数表示出 a,同样 也可以用这些数和a表示出 b,这样 b就可以替换成 a和那些数,同样能表示所有数。而 a的代价更小,结果会更优。因此是能插就插。

神奇的代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int count(int x){
int cnt = 0;
while(x){
cnt += (x & 1);
x >>= 1;
}
return cnt;
}
int p[32];
bool insert(int x) {
for (int i = 17; i + 1; i--) {
if (!(x >> i)) // x的第i位是0
continue;
if (!p[i]) {
p[i] = x;
return true;
}
x ^= p[i];
}
return false;
}
int main(void) {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int n;
cin >> n;
LL ans = 0;
vector<pair<LL,int> > qwq;
for(int i = 1; i < (1 << n); ++ i){
LL x;
cin >> x;
qwq.push_back({x, i});
}
sort(qwq.begin(), qwq.end());
for(auto i : qwq){
if (insert(i.second))
ans += i.first;
}
cout << ans << endl;
return 0;
}


本文作者:~Lanly~

本文链接:https://www.cnblogs.com/Lanly/p/15850262.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   ~Lanly~  阅读(158)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.