2021"MINIEYE杯"中超(5)补题
2021/8/13 6:06:17
本文主要是介绍2021"MINIEYE杯"中超(5)补题,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
2021"MINIEYE杯"中超(5)
1004 Another String
维护这么一个数组:f[i, j]表示以i,j为起点的两个子序列可以满足条件的最大长度。那么当t在i ~ i + f[i, j]这个区间时,f[i, j]对答案是有贡献的。当t在j及以后时,f[i, j]对答案是没有贡献的。所以我们可以在求出f[i, j]后,维护一个差分矩阵。对于每个f[i, j],ans[i] ++ , ans[i + f[i,j]] -- ;这表示在这个范围内f[i, j]的贡献,同时当分割点大于等于j时是没有贡献的。所以我们还要有 ans[j] -= f[i, j],ans[j + 1] += f[i, j]来消除此部分的贡献。
最后取两次前缀和即可得到答案。
#include <bits/stdc++.h> using namespace std; const int N = 3010; int t; int f[N][N];//f[i][j]表示以i,j为起点的两个子序列满足条件的最大长度 int n, k; char s[N]; int ans[N]; void solve() { cin >> n >> k; cin >> (s + 1); //尺取 for (int l = 2; l <= n; l ++ )//枚举右端点 { int len = 0, dif = 0;//len为当前满足的最长区间长度,dif为当前不同的位置有多少个 for (int i = 1, j = l; j <= n; i ++ , j ++ )//从两个区间的起点开始扫两个子序列 { while (dif <= k)//当满足条件的话继续往后移动 { dif += (s[i + len] != s[j + len]); len ++ ; } f[i][j] = min(len - 1, min(j - i, n - j + 1));//更新f[i][j] len -- ;//后移一位 dif -= (s[j] != s[i]); } } memset(ans, 0, sizeof ans); //差分矩阵更新 for (int i = 1; i <= n; i ++ ) for (int j = i + 1; j <= n; j ++ ) { ans[i] ++ ; ans[i + f[i][j]] -- ; ans[j] -= f[i][j]; ans[j + 1] += f[i][j]; } for (int i = 1; i <= n; i ++ ) ans[i] += ans[i - 1]; for (int i = 1; i <= n; i ++ ) ans[i] += ans[i - 1]; for (int i = 1; i < n; i ++ ) cout << ans[i] << endl; } int main() { ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); cin >> t; while (t -- ) solve(); return 0; }
1006 Cute Tree
模拟
#include <bits/stdc++.h> using namespace std; const int N = 2e5 + 10; int t; int n; int a[N]; struct node { int a[3]; }tr[N << 2]; int cnt; void build(int ro, int l, int r) { if (l == r) return; if (r == l + 1) { build(tr[ro].a[0] = ++ cnt, l, l); build(tr[ro].a[1] = ++ cnt, r, r); } else { int k = (r - l) / 3 + 1; int b = l + k - 1; int c = b + r >> 1; build(tr[ro].a[0] = ++ cnt, l, b); build(tr[ro].a[1] = ++ cnt, b + 1, c); build(tr[ro].a[2] = ++ cnt, c + 1, r); } } int main() { scanf("%d", &t); while (t -- ) { scanf("%d", &n); for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]); cnt = 1; build(1, 1, n); printf("%d\n", cnt); } return 0; }
1007 Banzhuan
比赛时由于我的原因想错了最优情况,导致思路错误,没有过掉题。。。
最大情况:往第n层放满,然后让它掉下去,放n次。
最小情况:XOY,XOZ,YOZ层放满。
比较坑的地方就是取模操作,由于有除法,直接相除取模会导致错误,所以要用到逆元。我们可以快速幂求得逆元。
#include <bits/stdc++.h> using namespace std; typedef long long LL; const LL MOD = 1e9 + 7; int t; LL n; LL qmi(LL a, LL k)//快速幂求逆元 { LL res = 1; while (k) { if (k & 1) res = (LL)res * a % MOD; k >>= 1; a = (LL)a * a % MOD; } return res; } void solve() { cin >> n; n %= MOD; LL a, b, c; a = (n % MOD * n % MOD) * (n + 1) % MOD * (n + 1) % MOD * (2 * n + 1) % MOD * qmi(12,MOD - 2) % MOD; b = (n - 1) % MOD * (n - 1) % MOD * (n + 2) % MOD * (n + 2) % MOD * qmi(4,MOD - 2) % MOD; c = (n - 1) % MOD * n % MOD * (n + 1) % MOD * (n + 2) % MOD * (2 * n + 1) % MOD * qmi(12,MOD-2) % MOD - (n + 2) % MOD * (n - 1) % MOD * qmi(2,MOD - 2)%MOD; LL r1 = ((a + b + c) % MOD + MOD) % MOD; LL r2 = n * n % MOD * n % MOD * (n + 1) % MOD * (n + 1) % MOD * (2 * n + 1) % MOD * qmi(12, MOD - 2) % MOD * n % MOD; cout << r1 << endl << r2 << endl; } int main() { cin >> t; while (t -- ) solve(); return 0; }
这篇关于2021"MINIEYE杯"中超(5)补题的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南