https://codeforces.com/contest/1763
A. Absolute Maximization二进制操作
经典的利用二进制位数操作的题,| 和 &。
最大值肯定是所有元素的或。
最小值是所有元素的与。
为什么?或就类似加法,每个位数有1的全都归并到一个数上,因此这个数是包含所有元素的每个位的1的,它必然是最大的。
与,则类似减法,把所有元素每一位的1都尝试减去,最终留下的是所有元素共同是1的位,也就是最小的。
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
void s(){
int n;
cin >> n;
vector<int> a(n);
for(auto &i : a) cin >> i;
int maxone = 0, minone = -1;
for(int i = 0; i < n; i ++){
maxone = maxone | a[i];
minone = minone & a[i];
}
cout << maxone - minone << endl;
}
int main(){
cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
int t;
cin >> t;
while(t--) s();
return 0;
}
B. Incinerate模拟
暴力模拟每一次attack就行,不会超时。
注意,有些元素是最小值,但是血很厚,需要反复杀很多次。有些元素动态的血量清零后,就不能再考虑它了。
实现思路:用一个all来存当前的累积伤害,如果这个怪物的血量低于累积伤害,说明它被kill了,将它弹掉或者忽略掉就行。
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
struct node{
int index;
long long hp, power;
};
long long n, k;
bool operator <(const struct node &a, const struct node &b){
return a.power > b.power; //小根堆
}
void s(){
cin >> n >> k;
vector<long long> h(n + 10), p(n + 10);// 别放全局变量
priority_queue<struct node> heap;
for(int i = 1; i <= n; i ++) cin >> h[i];
for(int j = 1; j <= n; j ++) cin >> p[j], heap.push({j, h[j], p[j]});
long long nowk = k, all = k;
while(!heap.empty() && nowk > 0){ //可能没kill,需要反复杀掉
while(!heap.empty() && heap.top().hp <= all) heap.pop();
while(!heap.empty() && heap.top().hp > all && nowk > 0){
nowk -= heap.top().power;
all += nowk;
}
}
while(!heap.empty() && heap.top().hp <= all) heap.pop();
if(!heap.empty()) {
cout << "NO\n";
}else cout << "YES\n";
}
int main(){
cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
int t;
cin >> t;
while(t--) s();
return 0;
}