Preface
作为一名半退役选手,个人感觉本场难度不是太大,感觉和去年比难度貌似是下降了。在打的时候实在是由于乱七八糟的原因(包括不限于眼瞎,眼瞎,还有眼瞎),打得一般般。
感觉本场模拟题偏多,实在是吃屎。
我会在代码一些有必要的地方加上注释,签到题可能一般就不会写了.
以下是代码火车头:- #include <iostream>
- #include
- #include <cstring>
- #include <cmath>
- #include <vector>
- #include <set>
- #include <queue>
- #include <map>
- #include <unordered_map>
- #include <iomanip>
- #define endl '\n'
- #define int long long
- #define rep(i,a,b) for(int i=(a);i<=(b);i++)
- #define rep2(i,a,b) for(int i=(a);i>=(b);i--)
- using namespace std;
- template<typename T>
- void cc(const vector<T> &tem) {
- for (const auto &x: tem) cout << x << ' ';
- cout << endl;
- }
- template<typename T>
- void cc(const T &a) { cout << a << endl; }
- template<typename T1, typename T2>
- void cc(const T1 &a, const T2 &b) { cout << a << ' ' << b << endl; }
- template<typename T1, typename T2, typename T3>
- void cc(const T1 &a, const T2 &b, const T3 &c) { cout << a << ' ' << b << ' ' << c << endl; }
- void cc(const string &s) { cout << s << endl; }
- void fileRead() {
- #ifdef LOCALL
- freopen("D:\\AADVISE\\Clioncode\\untitled2\\in.txt", "r", stdin);
- freopen("D:\\AADVISE\\Clioncode\\untitled2\\out.txt", "w", stdout);
- #endif
- }
- void kuaidu() { ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); }
- inline int max(int a, int b) {
- if (a < b) return b;
- return a;
- }
- inline double max(double a, double b) {
- if (a < b) return b;
- return a;
- }
- inline int min(int a, int b) {
- if (a < b) return a;
- return b;
- }
- inline double min(double a, double b) {
- if (a < b) return a;
- return b;
- }
- void cmax(int &a, const int &b) { if (b > a) a = b; }
- void cmin(int &a, const int &b) { if (b < a) a = b; }
- void cmin(double &a, const double &b) { if (b < a) a = b; }
- void cmax(double &a, const double &b) { if (b > a) a = b; }
- using PII = pair<int, int>;
- using i128 = __int128;
- using vec_int = std::vector<int>;
- using vec_char = std::vector<char>;
- using vec_double = std::vector<double>;
- using vec_int2 = std::vector<std::vector<int> >;
- using que_int = std::queue<int>;
复制代码 Problem E. 一起走很长的路!
一个很典典的题,简简单单推式子就好了,比\(C\)题简单不少。
设前缀和\(pre_i=a_1+a_2+...+a_i\),那么需要满足条件:\(pre_i-pre_{l-1}>=a_{i+1}\),\(l r1) return; if (l1 1; if (r1 r1) return info(); if (l1 1; if (r1 > T; while (T--) { cin >> n; int q; cin >> q; rep(i, 1, n) { cin >> A; pre += A; pre += pre[i - 1]; } seg.clear(1, n - 1); rep(i, 1, n-1) { dis = pre - A[i + 1]; seg.add(i, i, dis); } rep(i, 1, q) { int l, r; cin >> l >> r; int tem = seg.qry(l, r - 1).mmin; int ans = 0; if (tem < pre[l - 1]) { ans = pre[l - 1] - tem; } cc(ans); } } return 0;}[/code]Problem F. 一起找神秘的数!
稍微画一画就能发现,满足条件需要\(x=y\)。
具体推的话,可以用韦恩图画一下就好了,记住,‘或’是求并集,异或是去重,and 是求交集。- //--------------------------------------------------------------------------------
- const int N = 1e5 + 10;
- const int M = 1e6 + 10;
- const int mod = 1e9 + 7;
- const int INF = 1e16;
- int n, m, T;
- //--------------------------------------------------------------------------------
- //struct or namespace:
- //--------------------------------------------------------------------------------
- signed main() {
- fileRead();
- kuaidu();
- T = 1;
- //cin >> T;
- while (T--) {
- bool fl = 0;
- rep(i, 1, 7) {
- int a;
- cin >> a;
- if (a == 4 or a == 7) fl = 1;
- }
- if (!fl) cc("YES");
- else cc("NO");
- }
- return 0;
- }
复制代码 Problem G. 一起铸最好的剑!
直接模拟就好了,不要直接用\(pow\)函数就好。- //--------------------------------------------------------------------------------
- const int N = 5e5 + 10;
- const int M = 1e6 + 10;
- const int mod = 1e9 + 7;
- const int INF = 1e16;
- int n, m, T;
- int A[N];
- //--------------------------------------------------------------------------------
- //struct or namespace:
- //--------------------------------------------------------------------------------
- signed main() {
- fileRead();
- kuaidu();
- T = 1;
- //cin >> T;
- while (T--) {
- cin >> n;
- rep(i, 1, n) cin >> A[i];
- sort(A + 1, A + n + 1);
- // rep(i, 1, n) cc(A[i]);
- int val = A[(n + 1 + 1) / 2] - 1;
- cc(val);
- }
- return 0;
- }
复制代码 Problem H. 一起画很大的圆!
最吃屎的时候,交了\(12\)发才过,还是最后蒙过去的。
首先先读题,边界!一开始读题读成了内部也可以,然后就先固定了两个点在斜线,然后找了最接近斜线的横坐标的每一个点去判断,时间复杂度按理来说是横坐标或者纵坐标的差值,\(1\)秒应该是能勉强跑过才对的,但是\(wa\)了,要不就是\(t\)了。
然后发现是在边界上...,但是依旧不会,脑子已经秀逗了。
最后暴力枚举了角落边界和中间边界的位置,然后跑过的。(其实也是有直觉是感觉两个点在角落,一个点在另一个同侧的角落,但是不确定)- //--------------------------------------------------------------------------------
- const int N = 2e5 + 10;
- const int M = 1e6 + 10;
- const int mod = 1e9 + 7;
- const int INF = 1e16;
- int n, m, T;
- char s[N];
- //--------------------------------------------------------------------------------
- //struct or namespace:
- //--------------------------------------------------------------------------------
- signed main() {
- fileRead();
- kuaidu();
- T = 1;
- cin >> T;
- while (T--) {
- cin >> n >> m;
- if (n == m) {
- cc("NO");
- continue;
- }
- if (m >= n - m + 1) {
- if (n - m - 1 <= 25 and n >= 4 and m >= 3) {
- cc("YES");
- s[1] = 'a';
- s[n] = 'a';
- rep(i, n-m+1, m) s[i] = 'a';
- rep(i, 2, n-m+1-1) {
- s[i] = 'a' + i - 1;
- s[n - i + 1] = s[i];
- }
- rep(i, 1, n) { cout << s[i]; }
- cout << endl;
- }
- else {
- cc("NO");
- }
- }
- else {
- if (m - 1 + (n - m - m) <= 25) {
- cc("YES");
- int k = m - 1 + (n - m - m);
- int x = n - k - 2, y = k - x;
- rep(i, 1, x) { cout << char('a' + i); }
- cout << 'a';
- rep(i, x+1, x+y) { cout << char('a' + i); }
- cout << 'a';
- rep(i, 1, x) { cout << char('a' + i); }
- cout << endl;
- }
- else {
- cc("NO");
- }
- }
- }
- return 0;
- }
复制代码 Problem I. 一起看很美的日落!
一个典典的树形dp,但是赛时没有时间做了,应该是有铜+的难度的。
首先我们对于每一位可以独立看待,于是每个点的权值变成了0或者1,然后经典树形dp。
设\(dp_x\)是包含了\(x\)的联通块的\(ans\),\(f_{x,0}\)是联通块里0的个数,\(f_{x,1}\)同理,\(g_x\)是联通块大小。
然后考虑如何合并两个联通块:- //--------------------------------------------------------------------------------
- const int N = 2e5 + 10;
- const int M = 1e6 + 10;
- const int mod = 1e9 + 7;
- const int INF = 1e16;
- int n, m, T;
- int pre[N][31];
- int suf[N][31];
- string s;
- //--------------------------------------------------------------------------------
- //struct or namespace:
- //--------------------------------------------------------------------------------
- bool check(int len) {
- rep(i, 1, n) {
- int l = i, r = i + len - 1;
- if (l < 1 or r > n) break;
- if (pre[l - 1][s[l] - 'a'] or suf[r + 1][s[r] - 'a']) {
- return 1;
- }
- }
- return 0;
- }
- signed main() {
- fileRead();
- kuaidu();
- T = 1;
- //cin >> T;
- while (T--) {
- cin >> n;
- cin >> s;
- s = ' ' + s;
- rep(i, 1, n) {
- rep(j, 0, 25) pre[i][j] = pre[i - 1][j];
- pre[i][s[i] - 'a'] = 1;
- }
- rep2(i, n, 1) {
- rep(j, 0, 25) suf[i][j] = suf[i + 1][j];
- suf[i][s[i] - 'a'] = 1;
- }
- int ans = 0;
- int l = 0, r = n;
- while (l + 1 != r) {
- int mid = l + r >> 1;
- if (check(mid)) l = mid;
- else r = mid;
- }
- cc(l);
- }
- return 0;
- }
复制代码 我觉得式子很显然,大家看了就晓得了。代码很简洁,顺手抄了个题解的取模类。- //--------------------------------------------------------------------------------
- const int N = 2e5 + 10;
- const int M = 1e6 + 10;
- const int mod = 1e9 + 7;
- const int INF = 1e16;
- int n, m, T;
-
- //--------------------------------------------------------------------------------
- //struct or namespace:
- class SEG {
- #define xl x+x
- #define xr x+x+1
-
- //TODO 节点维护信息、apply函数、up函数
- struct info {
- int mmin = INF;
-
- void apply(int k) {
- mmin = k;
- }
-
- friend info operator+(const info &q1, const info &q2) {
- info q;
- q.mmin = min(q1.mmin, q2.mmin);
- return q;
- }
- };
-
- int L, R;
- info F[unsigned(N * 2.7)];
-
- void init(int x, int l, int r) {
- if (l == r) {
- F[x] = info();
- return;
- }
- int mid = l + r >> 1;
- init(xl, l, mid), init(xr, mid + 1, r);
- F[x] = F[xl] + F[xr];
- }
-
- void add(int x, int l, int r, int l1, int r1, int k) {
- if (l1 > r1) return;
- if (l1 <= l and r <= r1) {
- F[x].apply(k);
- return;
- }
- int mid = l + r >> 1;
- if (r1 <= mid) add(xl, l, mid, l1, r1, k);
- else if (mid < l1) add(xr, mid + 1, r, l1, r1, k);
- else add(xl, l, mid, l1, mid, k), add(xr, mid + 1, r, mid + 1, r1, k);
- F[x] = F[xl] + F[xr];
- }
-
- info qry(int x, int l, int r, int l1, int r1) {
- if (l1 > r1) return info();
- if (l1 <= l and r <= r1) return F[x];
- int mid = l + r >> 1;
- if (r1 <= mid) return qry(xl, l, mid, l1, r1);
- else if (mid < l1) return qry(xr, mid + 1, r, l1, r1);
- else { return qry(xl, l, mid, l1, mid) + qry(xr, mid + 1, r, mid + 1, r1); }
- }
- #undef xl
- #undef xr
-
- public:
- void clear(int l, int r) {
- L = l, R = r;
- init(1, l, r);
- }
-
- void add(int l, int r, int k) { add(1, L, R, l, r, k); }
- info qry(int l, int r) { return qry(1, L, R, l, r); }
- };
-
- SEG seg;
- int A[N], pre[N], dis[N];
- //--------------------------------------------------------------------------------
-
- signed main() {
- fileRead();
- kuaidu();
- T = 1;
- //cin >> T;
- while (T--) {
- cin >> n;
- int q;
- cin >> q;
- rep(i, 1, n) {
- cin >> A[i];
- pre[i] += A[i];
- pre[i] += pre[i - 1];
- }
- seg.clear(1, n - 1);
-
- rep(i, 1, n-1) {
- dis[i] = pre[i] - A[i + 1];
- seg.add(i, i, dis[i]);
- }
-
- rep(i, 1, q) {
- int l, r;
- cin >> l >> r;
- int tem = seg.qry(l, r - 1).mmin;
- int ans = 0;
- if (tem < pre[l - 1]) {
- ans = pre[l - 1] - tem;
- }
- cc(ans);
- }
-
- }
- return 0;
- }
复制代码 Problem L. 还会再见吗?
看了题解,虚树。
于是直接再见。
学虚树不如继续搞开发。
Problem M. 那是我们的影子
赛时没有做出来,赛后看题解发现不算太难。
但是个人感觉难度应该和\(I\)差不多才对。只能说这种题自己总会写的复杂,感慨大佬写的代码很简洁。
感觉官方题解写的很好很清楚,建议去看(不是自己懒了
借鉴了\(Heltion\)的代码:- //--------------------------------------------------------------------------------
- const int N = 5e5 + 10;
- const int M = 1e6 + 10;
- const int mod = 1e9 + 7;
- const int INF = 1e16;
- int n, m, T;
- int A[N];
- //--------------------------------------------------------------------------------
- //struct or namespace:
- //--------------------------------------------------------------------------------
- signed main() {
- fileRead();
- kuaidu();
- T = 1;
- //cin >> T;
- while (T--) {
- cin >> n;
- rep(i, 1, n) {
- int a, b;
- cin >> a >> b;
- cc(b - a + 1);
- }
- }
- return 0;
- }
复制代码 PostScript
只能说自己吃屎吃得太多,有些题自己写的太烂,点名批评\(h\)题。
感觉难度比去年真的少了很多,不知道是不是错觉。
题解如果有误希望可以指出来。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |