A.小乔和小灰灰
签到。
Code
/*
* Author: heyuhhh
* Created Time: 2020/3/13 19:00:59
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '
'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1000 + 5;
const string s = "XiaoQiao", t = "XiaoHuiHui";
string ss;
void run() {
cin >> ss;
int len = ss.length();
int t1 = 0, t2 = 0;
for(int i = 0; i < len; i++) {
if(t1 < 8 && ss[i] == s[t1]) ++t1;
if(t2 < 10 && ss[i] == t[t2]) ++t2;
}
if(t1 == 8 && t2 == 10) {
cout << "Happy" << '
';
} else cout << "emm" << '
';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}
B.牛能和小镇
排序后贪心计算即可。
Code
/*
* Author: heyuhhh
* Created Time: 2020/3/13 19:12:53
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '
'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
int n;
ll a[N];
void run() {
cin >> n;
for(int i = 1; i <= n; i++) {
int x, y; cin >> x >> y;
a[i] = 1ll * y * (x - y) * (x - y);
}
sort(a + 1, a + n + 1);
ll ans = 0;
for(int i = 2; i <= n; i++) {
ans += a[i] - a[i - 1];
}
cout << ans << '
';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}
C.装备合成
题意:
牛牛有({x})件材料(a)和({y})件材料(b),用(2)件材料(a)和(3)件材料(b)可以合成一件装备,用(4)件材料(a)和(1)件材料(b)也可以合成一件装备。牛牛想要最大化合成的装备的数量,于是牛牛找来了你帮忙。
思路:
显然最终答案具有单调性。
那么二分答案(t),假设最后用第一种方法合成了(A)件装备,那么第二种方法合成了(B)件装备,那么可以列出如下式子:
- (2A+4Bleq x,3A+Bleq y,A+B=t).
最后可以解出(A)的范围。二分时(check)一下是否合法即可。
Code
/*
* Author: heyuhhh
* Created Time: 2020/3/13 19:21:23
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '
'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
ll a, b;
bool chk(ll t) {
ll l = ceil(1.0 * (4 * t - a) / 2), r = floor(1.0 * (b - t) / 2);
return l <= r && l <= t && r >= 0;
}
void run() {
cin >> a >> b;
int l = 0, r = INF, mid;
while(l < r) {
mid = (l + r) >> 1;
if(chk(mid)) l = mid + 1;
else r = mid;
}
cout << l - 1 << '
';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
int T; cin >> T;
while(T--) run();
return 0;
}
D.取石子游戏
(sg)函数有规律,直接算就行。
Code
/*
* Author: heyuhhh
* Created Time: 2020/3/13 20:15:51
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '
'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
ll f[N];
int t;
void init() {
ll Max = 4e18;
f[1] = 1, f[2] = 3;
for(int i = 3;; i++) {
f[i] = f[i - 1] * 2;
if(i % 2 == 0) ++f[i];
if(f[i] >= Max) {
t = i; break;
}
}
}
void run() {
ll n; cin >> n;
int p = lower_bound(f + 1, f + t + 1, n) - f;
if(p & 1) cout << "XiaoQiao" << '
';
else cout << "XiaoHuiHui" << '
';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
init();
int T; cin >> T;
while(T--) run();
return 0;
}
E.石子搬运
题意:
现有(n)堆石子,每堆有(a_i)个石头。现在可以将这(n)堆石子划分为(m)堆,每堆贡献为(k_i^2)。
然后会发生(q)个事件,每个事件为(x v),即将第(x)堆石子个数变为(v)。
对于每个事件,回答最小贡献。
(1leq nleq mleq 400,qleq 400)。
思路:
对于每个事件我们单独计算,总体思路就是贪心,按照差值来进行贪心。
每次选择当前贡献能减少的最大值进行操作即可。
可以用一个优先队列来维护。shi
时间复杂度为(O(qnlogn))。
代码如下:
Code
/*
* Author: heyuhhh
* Created Time: 2020/3/13 23:06:41
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '
'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 400 + 5;
int n, m, q;
int a[N];
ll calc(int v, int k) {
int r = v % k;
int t = v / k;
return 1ll * r * (t + 1) * (t + 1) + 1ll * (k - r) * t * t;
}
ll solve(int v, int k) {
return calc(v, k) - calc(v, k + 1);
}
void run() {
cin >> n >> m;
for(int i = 1; i <= n; i++) cin >> a[i];
cin >> q;
while(q--) {
int id, v; cin >> id >> v;
a[id] = v;
priority_queue <pair<ll, pii>> q;
for(int i = 1; i <= n; i++) {
q.push(pair<ll, pii>{solve(a[i], 1), MP(a[i], 1)});
}
int k = m - n;
while(k--) {
pair <ll, pii> now = q.top(); q.pop();
int val = now.se.fi, t = now.se.se + 1;
q.push(pair<ll, pii>{solve(val, t), MP(val, t)});
}
ll ans = 0;
while(!q.empty()) {
pair <ll, pii> now = q.top(); q.pop();
int val = now.se.fi, t = now.se.se;
ans += calc(val, t);
}
cout << ans << '
';
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}
F.小松鼠吃松果
题意:
有(m)个位置,有(n)个时刻在某些位置会生长一个价值为(v_i)的果子,每个果子只会存在一秒。
现在你可以任意选择一个点作为起点,每一秒只能向左或者向右移动一步。问最后能得到的最大价值是多少。
思路:
我们按照时间进行排序,如果我们要吃至少两个果子,那么要满足的条件为:
- (t_j-t_igeq |p_i-p_j|)。
我们将绝对值打开,有:
- (p_igeq p_j,t_j+p_jgeq t_i+p_i);
- (p_i<p_j,t_j-p_jgeq t_i-p_i)。
那么令(X_i=p_i+t_i,Y_i=t_i-p_i)。
那么我们按照(X_i)进行排序,问题可以转化为带权(lis),(Y_i)就是每个数的高度。我们要求最长不下降子序列的最大权值和。利用树状数组维护即可。
注意这里我们将问题转化为了二维问题。我们推出第二个式子的前提是按照时间排序,又可以发现只要满足第二个式子,第一个式子也自然满足了。如果没注意到这一点,就是一个三维问题,就像题解那样用树套树或者(cdq)分治这些来解决。
代码如下:
Code
/*
* Author: heyuhhh
* Created Time: 2020/3/14 10:23:00
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '
'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
int n, m;
int a[N], b[N];
struct node {
int id, h, v;
bool operator < (const node &A) const {
if(id != A.id) return id < A.id;
return h < A.h;
}
}info[N];
struct BIT {
ll c[N];
int lowbit(int x) {return x & (-x);}
void upd(int x, ll v) {
for(; x < N; x += lowbit(x)) c[x] = max(c[x], v);
}
ll query(int x) {
ll res = 0;
for(; x; x -= lowbit(x)) res = max(res, c[x]);
return res;
}
}bit;
void run() {
cin >> n >> m;
for(int i = 1; i <= m; i++) cin >> a[i];
for(int i = 1; i <= m; i++) cin >> b[i];
for(int i = 1; i <= n; i++) {
int t, p, c; cin >> t >> p >> c;
int x = a[p], y = b[p] + t;
info[i] = node{y - x, x + y, c};
}
sort(info + 1, info + n + 1);
vector <int> v;
for(int i = 1; i <= n; i++) v.push_back(info[i].h);
sort(all(v));
v.erase(unique(all(v)), v.end());
for(int i = 1; i <= n; i++) {
int h = lower_bound(all(v), info[i].h) - v.begin() + 1;
bit.upd(h, bit.query(h) + info[i].v);
}
ll ans = bit.query(n);
cout << ans << '
';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}