湖南多校第二场

按照个人难度排序,没写的就是不是我写的,指路[队友blog]

I

签到题,忘记了

D

队友写的

B

判断Alice能否获胜只需要折半查找
发现对于n>3的情况Bob不可能能走遍所有格子,Alice至少能平局。(手模可以证明)
所以对于n<=3的情况暴搜即可

H

纯暴力题。。本来想了一个细节做法,就是确定一个点的位置往后面找其他两个点。队友说可以n方预处理两点关系然后 \(n^3\) 统计答案

J

每次只和相邻的飞机有关,所以把序列看为一个链表,每次取权值最小的边和点一起删掉就可以。优先队列+链表+线段树

K

猜结论

F

每次询问的时候对询问点排序然后挨个lca后缀,看能否符合答案

E

dp+数据结构优化
dp思路就是分三种情况,转移点有两维限制,一维是两个字母相等,另一维是出现次数,用数据结构统计即可。
尝试写了一个树状数组+离散化做法,原本写错写成离散化3次,mle了。但是其实要离散化3*n次,此过程中需要多开许多个vector,我觉得非常构式,所以还是建议写线段树吧。
线段树常数比平衡树以及离散化会小一些,但是空间是 \(nlog(n)\)
这里有一个点我也不是很懂,就是N要开到1e6+2或者要把MXL设为0,不然就会死循环以至于MLE

#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+2, maxn = 1e3 + 7, mod = 998244353;
using i64 = long long;
#define MXL 1
#define MXR 2e6 + 5
#define lowbit(x) (x & (-x))
// #define int long long
int k, n, m, dip[N], dic[N], dpc[N], f[N];
void add(int &x, int y) {
    x = 1ll*(x + y > mod) ? (x + y - mod) : (x + y);
}
int mul(int x, int y) {
    return 1ll * x * y % mod;
}
struct Tree{
    int ls[N*25], rs[N*25], root[N], sum[N*25], tot = 0;
    // t[k][num][x] 树状数组存储的是第num种情况,相等值为k,差值为x
    void init() {
        memset(ls, 0, sizeof(ls));
        memset(rs, 0, sizeof(rs));
        memset(root, 0, sizeof(root));
        memset(sum, 0, sizeof(sum));
        tot = 0;
    }
    int que(int x, int l, int r, int qr) {
        // cout << l << r <<' '<<qr<< endl;
        if (r <= qr) {
            return sum[x];
        }
        int mid = (l + r) / 2;
        int res = 0;
        add(res, que(ls[x], l, mid, qr));
        if (mid < qr) add(res, que(rs[x], mid + 1, r, qr));
        return res;
    }
    void upd(int &x, int l, int r, int q, int val) {
        if (!x) x = ++tot;
        add(sum[x], val);
        if (l == r) {
            return;
        }
        int mid = (l + r) / 2;
        if (q <= mid) upd(ls[x], l, mid, q, val);
        else upd(rs[x], mid + 1, r, q, val);
    }
}t[3];

void solve() {
    string s; cin >> s; s = ' ' + s;
    int len = s.size() - 1, mn = N;
    vector<int>dc(len + 1, 0), di(len + 1, 0), dp(len + 1, 0);
    for (int i = 0; i < 3; i++) t[i].init();
    //IP
    dc[0] = di[0] = dp[0] = N;
    for (int i = 1; i <= len; i++) {
        dip[i] = dip[i - 1]; 
        dc[i] = dc[i - 1];
        if (s[i] == 'I') dip[i]++, dc[i]--;
        else if (s[i] == 'P') dip[i]--;
        else dc[i]++;
        mn = min(mn, dip[i]);
    }
    if (mn <= 0) {
        mn = -mn + 1;
        for (int i = 0; i <= len; i++) dip[i] += mn;
    }
    //IC
    mn = N;
    for (int i = 1; i <= len; i++) {
        dic[i] = dic[i - 1]; 
        dp[i] = dp[i - 1];
        if (s[i] == 'I') dic[i]++, dp[i]--;
        else if (s[i] == 'C') dic[i]--;
        else dp[i]++;
        mn = min(mn, dic[i]);
    }
    if (mn <= 0) {
        mn = -mn + 1;
        for (int i = 0; i <= len; i++) dic[i] += mn;
    }

    //PC
    mn = N;
    for (int i = 1; i <= len; i++) {
        dpc[i] = dpc[i - 1]; 
        di[i] = di[i - 1];
        if (s[i] == 'C') dpc[i]++, di[i]--;
        else if (s[i] == 'P') dpc[i]--;
        else di[i]++;
        mn = min(mn, dpc[i]);
    }
    if (mn <= 0) {
        mn = -mn + 1;
        for (int i = 0; i <= len; i++) dpc[i] += mn;
    }
    //cnt
    t[0].upd(t[0].root[dip[0]], MXL, MXR, dc[0], 1);
    t[1].upd(t[1].root[dic[0]], MXL, MXR, dp[0], 1);
    t[2].upd(t[2].root[dpc[0]], MXL, MXR, di[0], 1);
        // cout << "dc "<<dc[0] <<" dp "<<dp[0]<<" di "<<di[0] << endl; 
        // cout << "dip "<<dip[0] <<" dic "<<dic[0]<<" dpc "<<dpc[0] << endl;
    // cout << "X? "<<endl;
    for (int i = 1; i <= len; i++) {
        // cout << i << endl;
        // cout << "dc "<<dc[i] <<" dp "<<dp[i]<<" di "<<di[i] << endl; 
        // cout << "dip "<<dip[i] <<" dic "<<dic[i]<<" dpc "<<dpc[i] << endl;
        add(f[i], t[0].que(t[0].root[dip[i]], MXL, MXR, dc[i] - 1));
        add(f[i], t[1].que(t[1].root[dic[i]], MXL, MXR, dp[i] - 1));
        add(f[i], t[2].que(t[2].root[dpc[i]], MXL, MXR, di[i] - 1));
        t[0].upd(t[0].root[dip[i]], MXL, MXR, dc[i], f[i]);
        t[1].upd(t[1].root[dic[i]], MXL, MXR, dp[i], f[i]);
        t[2].upd(t[2].root[dpc[i]], MXL, MXR, di[i], f[i]);
        // cout << f[i] << endl;
    }
    cout << f[len] << endl;
}
signed main() {
	ios::sync_with_stdio(false);
	int t = 1;
	// cin >> t;
	while(t--) solve();

}

A

我不会

posted @ 2025-03-19 11:47  lyrrr  阅读(21)  评论(0)    收藏  举报