第十一场训练赛
A - AAA
思路:
典型的贪心,在能搬动的情况下,如果值为负数就带走
#include<bits/stdc++.h>
using namespace std;
int main() {
//freopen("in.txt", "r", stdin);
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int n, m;cin >> n >> m;
int a[100];
for (int i = 0; i < n; ++i)cin >> a[i];
sort(a, a + n);
int cnt = 0;
for (int i = 0; i < m; ++i)if (a[i] < 0)cnt += abs(a[i]);
cout << cnt;
}
B - BBB
思路:
数学问题,在满足能点构成的边会小于 \(m\) 时不断++
,此时cnt是最大能连接的点
\[Min:min(0,n - 2 * m)\\
Max:n - cnt
\]
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n, m, Min = 0, Max = 0;
int main() {
//freopen("in.txt", "r", stdin);
ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> n >> m;
ll cnt = 0;
while (cnt * (cnt - 1) / 2 < m)cnt++;
cout << max((ll)0, n - 2 * m) << " " << n - cnt << endl;
}
C - CCC
思路:差分统计每个高度i有的方块数h[i],然后从高到低贪心的切就行了
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 200000;
ll _, n, m, k, vis[N + 10];
int main() {
//freopen("in.txt", "r", stdin);
ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> n >> k;
for (int i = 0; i < n; i++) { int x; cin >> x; vis[x]++; }
ll cnt = 0, t = 0;
for (ll i = N; i > 0; --i) {
if (vis[i] == n)break;
if (vis[i] + t > k) {
t = vis[i], cnt++;
}
else
t += vis[i];
vis[i - 1] += vis[i];
}
cout << (t ? cnt + 1 : cnt) << endl;
}
D - DDD
题意:
这个题把,应该算是思维题,最后出门的时候,带上最靠近门口的快递,其他的随便怎么拿,每拿一次就要回到K按一次密码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll _, n, m, k;
string anw[2] = { "YES\n","NO\n" };
void solve() {
cin >> n >> m >> k;
//int a[m + 1];
ll a[m + 1], sum = 0;
for (int i = 1; i <= m; ++i) cin >> a[i];
sort(a + 1, a + 1 + m);
sum += k - 1;
for (int i = m; i > 1; i--) {
sum += 2 * abs(a[i] - k);
}
sum += abs(a[1] - k) + a[1] - 1;
cout << sum << endl;
}
int main() {
//freopen("in.txt", "r", stdin);
ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> _; while (_--)solve();
}
E - EEE (签到题)
简单理解题意即可,签到
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll _, n;
string anw[2] = { "YES\n","NO\n" };
void solve() {
cin >> n;
int a[n + 1];
for (int i = 1; i <= n; ++i)cin >> a[i];
for (int i = 2; i <= n; ++i)if (a[i] == a[i - 1]) { cout << anw[1]; return; }
cout << anw[0];
}
int main() {
//freopen("in.txt", "r", stdin);
ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> _; while (_--)solve();
}
F - 做出来算我输
涉及算法:Min25筛 1e10
题意:
n个点的完全图,边权为lcm(i+1,j+1),求mst(最小生成树)
参考:https://blog.csdn.net/qq_39972971/article/details/81543972
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 1000010;
ll n, mod;
ll q_pow(ll a, ll b) {//快速取幂
ll ans = 1;
while (b){
if (b & 1)
ans = ans * a % mod;
a = a * a % mod;
b /= 2;
}
return ans % mod;
}
ll prime[N], id1[N], id2[N], flag[N], ncnt, m;
ll g[N], sum[N], a[N], T;
inline ll ID(ll x) {
return x <= T ? id1[x] : id2[n / x];
}
inline ll calc(ll x) {
return x * (x + 1) / 2 - 1;
}
inline ll f(ll x) {
return x;
}
inline void init() {
ncnt = m = 0;
T = sqrt(n + 0.5);
for (ll i = 2; i <= T; i++)
{
if (!flag[i])
prime[++ncnt] = i, sum[ncnt] = sum[ncnt - 1] + i;
for (ll j = 1; j <= ncnt && i * prime[j] <= T; j++)
{
flag[i * prime[j]] = 1;
if (i % prime[j] == 0)
break;
}
}
for (ll l = 1; l <= n; l = n / (n / l) + 1)
{
a[++m] = n / l;
if (a[m] <= T)
id1[a[m]] = m;
else
id2[n / a[m]] = m;
g[m] = calc(a[m]);
}
for (ll i = 1; i <= ncnt; i++)
for (ll j = 1; j <= m && (ll)prime[i] * prime[i] <= a[j]; j++)
g[j] = g[j] - (ll)prime[i] * (g[ID(a[j] / prime[i])] - sum[i - 1]);
}
inline ll solve(ll x) {
if (x <= 1)return x;
return n = x, init(), g[ID(n)];
}
int main() {
//freopen("in.txt", "r", stdin);
ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int _; cin >> _;
ll n;
while (_--) {
cin >> n >> mod;
ll ans = (solve(n + 1) - 2 + mod) % mod;//质数和
ll inv2 = q_pow(2, mod - 2) % mod;
ll tmp = ((n + 4) % mod * (n - 1) % mod) % mod * inv2 % mod;
cout << (ans + tmp) % mod << endl;
}
}