1. G-Game of Swapping Numbers
给定序列 A , B A,B A,B,需要交换恰好 k k k 次 A A A 中两个不同的数,使得 A , B A,B A,B 每个位置的绝对差值和最大。 N ≤ 100000 N \le 100000 N≤100000
一道有点像的题目
[D. Swapping Problem](Problem - F - Codeforces)
- 思路:直接看题解:
#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef long long ll;
int n;
const int N = 200010;
ll a[N], b[N];
int main()
{
scanf("%d", &n);
map<ll, ll> segX, segY;
for(int i = 1; i <= n; i++) scanf("%lld", &a[i]);
for(int i = 1; i <= n; i++) scanf("%lld", &b[i]);
for(int i = 1; i <= n; i++){
if(a[i] <= b[i]){
if(!segX.count(a[i])) segX[a[i]] = b[i];
else segX[a[i]] = max(segX[a[i]], b[i]);
}
else{
if(!segY.count(b[i])) segY[b[i]] = a[i];
else segY[b[i]] = max(segY[b[i]], a[i]);
}
}
ll mx = -1e18;
for(auto & p : segX){
mx = max(mx, p.y);
p.y = mx;
}
mx = -1e18;
for(auto & p : segY){
mx = max(mx, p.y);
p.y = mx;
}
ll res = 0, ans = 0;
//当 a[i] <= b[i] 的时候,我们只关心 b[j] <= a[i] 的情况,因为另外一种情况可以在 a[i] > b[i] 的时候考虑到.
for(int i = 1; i <= n; i++){
if(a[i] <= b[i]){
//因为it.y 保存的是左端点从 -inf ~ it.x 的,右端点的最大值.
auto it = segY.upper_bound(a[i]);
if(it == segY.begin()) continue;
it--;
res = max(res, 2LL * (min(it->y, b[i]) - a[i]));
}
else{
auto it = segX.upper_bound(b[i]);
if(it == segX.begin()) continue;
it--;
res = max(res, 2LL * (min(it->y, a[i]) - b[i]));
}
}
for(int i = 1; i <= n; i++) ans += abs(a[i] - b[i]);
cout << ans - res << endl;
}
2. K-Knowledge Test about Match
Display Substring - HDU 6988 - Virtual Judge (vjudge.net)
后缀自动机
3. Another String - HDU 7015 - Virtual Judge (vjudge.net)
双指针弄一弄
4. Median - HDU 7029 - Virtual Judge (vjudge.net)
贪心
5. Decomposition - HDU 7028 - Virtual Judge (vjudge.net)
奇妙构造