AtCoder Beginner Contest 141
AtCoder Beginner Contest 141
https://atcoder.jp/contests/abc141
D - Powerful Discount Tickets
贪心 + 堆
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e5 + 5;
int a[N], n, m, f[N]; //f[i]:用了几张
ll ans;
int main () {
cin >> n >> m;
//用几张
for (int i = 1; i <= n; i++) cin >> a[i], ans += a[i];
priority_queue<int> q;
for (int i = 1; i <= n; i++) {
int t = a[i];
while (t > 0) q.push (t - t / 2), t /= 2;
}
while (!q.empty () && m --) {
//cout << q.top () << endl;
ans -= q.top ();
q.pop ();
}
cout << ans;
}
//dp
E - Who Says a Pun?
字符串中找到两个最长的一样的不重叠子串
最最最简单的dp
#include <bits/stdc++.h>
#define vi vector<int>
using namespace std;
const int N = 5e3 + 5;
int n, f[N][N], ans; //f[i][j]: i结尾与j结尾的匹配的最大长度
string s;
int main () {
cin >> n >> s;
s = ' ' + s;
for (int i = 1; i <= n; i++) {
for (int j = i + 1; j <= n; j++) {
if (s[i] == s[j]) {
if (i + f[i-1][j-1] < j) f[i][j] = f[i-1][j-1] + 1;
ans = max (ans, f[i][j]);
}
}
}
cout << ans;
}
//dp
F - Xor Sum 3
不会写,没想到是线性基。
洛谷题解:https://www.luogu.com.cn/problem/solution/AT_abc141_f
啊啊又是位运算 1ll<<
这里!!太可恶了!!
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 5;
int a[N], cnt[63];
int n, ans;
struct linear_basis {
int num[63];
bool insert (int x) {
for (int i = 60; i >= 0; i--) {
if ((x >> i & 1) == 0) continue;
if (num[i] == 0) {
num[i] = x;
return true;
}
else x ^= num[i];
}
return false;
}
int query () {
int x = 0;
for (int i = 62; i >= 0; i --) {
x = max (x, x ^ num[i]);
}
return x;
}
}T;
signed main () {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
for (int j = 60; j >= 0; j--) cnt[j] += (a[i] >> j & 1);
}
for (int j = 60; j >= 0; j--) {
if (cnt[j] % 2 == 0) continue;
ans += (1ll << j); //奇数贡献一直在
for (int i = 1; i <= n; i++) {
if (a[i] >> j & 1) {
a[i] ^= (1ll << j);
}
}
}
for (int i = 1; i <= n; i++) T.insert (a[i]);
cout << ans + 2 * T.query () << endl;
}
//划分成两部分,使得每部分的异或和最大
//恰好符合线性鸡定义
//找到最大ai
//按位考虑:当前位1次数为奇数->直接计入,偶数->x1^x2=0,x1取max,则x2取max