2022 ICPC 杭州
https://codeforces.com/gym/104090
唉我还是太菜了
A.Modulo Ruins the Legend
纠正一下:第一种情况最小是sum2 第二种情况最坏是sum2 可以比sum2更小
为什么? 因为g是m的因数 所以后面就会循环了
题解中说明:其实d只用取0或者1 因为相当于对每个位置加上一个平均数 也就只加了ns 但是可能这个平均数可能为分数 所以d取1和0即可代表所有情况
#include <bits/stdc++.h>
#define endl "\n"
#define INF 0x3f3f3f3f
#define LLINF 0x3f3f3f3f3f3f3f3f
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
ll exgcd(ll a, ll b, ll& x, ll& y) {
if (!b) {
x = 1, y = 0;
return a;
}
ll d = exgcd(b, a % b, x, y);
ll tx = x;
x = y, y = tx - y * (a / b);
return d;
}
signed main() {
IOS;
ll n, mod; cin >> n >> mod;
ll sum = 0;
for (int i = 1; i <= n; i++) {
ll t; cin >> t;
sum += t;
}
ll a = n, b = n * (n + 1) / 2;
ll s, dt;
ll d = exgcd(a, b, s, dt);
sum %= mod;
ll k, t;
ll g = exgcd(d, mod, k, t);
ll z = (mod - sum + g - 1) / g;
(k *= z) %= mod;
s = ((s % mod * k) % mod + mod) % mod, dt = ((dt % mod * k) % mod + mod) % mod;
cout << (z * g + sum - mod) << endl;
cout << s << " " << dt << endl;
}
C. No Bug No Game
分析:
选物品的顺序很重要 但是题目并没有要求顺序
有一个关键的性质 最多只有一个物品是取不完的
此时会有疑问 当前转移到i 后面的不是还没转移嘛
其实并不是 因为最多只有一个物品取不完 后面的还是按照都选的转移即可
const int N = 3010;
long long dp[N][N][5];
void Immortality()
{
int n, k;
cin >> n >> k;
long long sum = 0;
vector<vector<int>> p(n + 1);
for (int i = 1; i <= n; i++)
{
int t;
cin >> t;
sum += t;
p[i].resize(t + 1);
for (int j = 1; j <= t; j++)
cin >> p[i][j];
}
if (sum <= k)
{
long long ans = 0;
for (int i = 1; i <= n; i++)
{
int t = (p[i].size() - 1);
ans += p[i][t];
}
cout << ans << endl;
return;
}
memset(dp, -0x3f, sizeof dp);
dp[0][0][1] = 0;
dp[0][0][0] = 0;
for (int i = 1; i <= n; i++)
{
int t = (p[i].size() - 1);
for (int j = 0; j <= k; j++)
{
dp[i][j][0] = dp[i - 1][j][0];
dp[i][j][1] = dp[i - 1][j][1];
if (j >= t)
{
dp[i][j][0] = max(dp[i - 1][j][0], dp[i - 1][j - t][0] + p[i][t]);
dp[i][j][1] = max(dp[i - 1][j][1], dp[i - 1][j - t][1] + p[i][t]);
}
for (int z = 1; z < t; z++)
if (j >= z)
dp[i][j][0] = max(dp[i][j][0], dp[i - 1][j - z][1] + p[i][z]);
}
}
cout << max(dp[n][k][1], dp[n][k][0]) << endl;
}
K. Master of Both
题意:根据设置的字符大小顺序
求字符串逆序对的个数
分析:
很明显 我们不能对每一种字符顺序求一次逆序对
#include "bits/stdc++.h"
using namespace std;
using i64 = long long;
constexpr int N = 26;
constexpr int M = 2E6;
i64 cnt[M + 10];
i64 add;
i64 num[N][N];
i64 ed[M + 10];
class Trie {
public:
int tot;
vector<vector<int>> t;
Trie(const int &n = 2E6) : t(n, vector<int>(N)), tot(0) {}
inline void insert(const string &s) {
int SIZE = s.size();
int u = 0;
for (int i = 0; i < SIZE; i++) {
int c = s[i] - 'a';
for (int j = 0; j < N; j++) {
if (c != j && t[u][j]) {
num[c][j] += cnt[t[u][j]];
}
}
if (t[u][c] == 0) {
t[u][c] = ++tot;
}
u = t[u][c];
cnt[u]++;
}
ed[u]++;
add += cnt[u] - ed[u];
}
};
void solve() {
int n, q;
cin >> n >> q;
Trie tree;
for (int i = 0; i < n; i++) {
string s;
cin >> s;
tree.insert(s);
}
for (int i = 0; i < q; i++) {
string s;
cin >> s;
i64 ans = 0;
for (int j = 0; j < N; j++) {
for (int k = j + 1; k < N; k++) {
ans += num[s[j] - 'a'][s[k] - 'a'];
}
}
cout << ans + add << '\n';
}
}
int main() {
int tt = 1;
while (tt--) {
solve();
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】