AtCoder Beginner Contest 339 A-G

A

模拟即可

void solve()
{
    string s;
    cin >> s;
    for (int i = s.size() - 1; i >= 0; i--)
        if (s[i] == '.')
        {
            cout << s.substr(i + 1) << endl;
            return;
        }
}

B

模拟,可以让下标从0开始,这样可以在%n下满足题意

int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
void solve()
{
    int n, m, opt;
    cin >> n >> m >> opt;
    vector<vector<char>> a(n, vector<char>(m, '.'));
    int d = 0, x = 0, y = 0;
    while (opt--)
    {
        if (a[x][y] == '.')
        {
            a[x][y] = '#';
            d = (d + 1) % 4;
        }
        else
        {
            a[x][y] = '.';
            d = (d - 1 + 4) % 4;
        }
        x = (x + dx[d] + n) % n;
        y = (y + dy[d] + m) % m;
    }
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
            cout << a[i][j];
        cout << endl;
    }
}

C

从后往前吗模拟:
设当前最少有x人
如果是\(a[i]<0\),则在到达该站前至少\(abs(a[i])\)
如果是\(a[i]>0\),则在到达该站前可以少\(abs(a[i])\)
最后再顺着模拟一遍得到答案

void solve()
{
    ll n;
    cin >> n;
    vector<ll> a(n + 1);
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    ll ans = 0;
    for (int i = n; i >= 1; i--)
    {
        if (a[i] > 0)
        {
            ans -= a[i];
            ans = max(0ll, ans);
        }
        else
            ans -= a[i];
    }
    for (int i = 1; i <= n; i++)
        ans += a[i];
    cout << ans << endl;
}

D

同时维护两人的坐标,进行bfs

ll dist[70][70][70][70];
int d[4][4] = {{-1, 1, 0, 0}, {0, 0, -1, 1}, {-1, 1, 0, 0}, {0, 0, -1, 1}};
void solve()
{
    int n, cnt = 0;
    cin >> n;
    array<int, 4> st;
    vector<vector<char>> a(n + 1, vector<char>(n + 1));
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
        {
            cin >> a[i][j];
            if (a[i][j] == 'P')
                st[cnt++] = i, st[cnt++] = j;
        }
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            for (int k = 1; k <= n; k++)
                for (int l = 1; l <= n; l++)
                    dist[i][j][k][l] = 1e9;

    auto bfs = [&](array<int, 4> x) -> void
    {
        queue<array<int, 4>> q;
        q.push(x);
        dist[x[0]][x[1]][x[2]][x[3]] = 0;
        while (q.size())
        {
            auto t = q.front();
            q.pop();
            for (int i = 0; i < 4; i++) // 方向
            {
                array<int, 4> tmp;
                for (int j = 0; j < 4; j++)
                {
                    tmp[j] = t[j] + d[j][i];
                    tmp[j] = min(n, tmp[j]);
                    tmp[j] = max(1, tmp[j]);
                }
                if (a[tmp[0]][tmp[1]] == '#')
                    tmp[0] = t[0], tmp[1] = t[1];
                if (a[tmp[2]][tmp[3]] == '#')
                    tmp[2] = t[2], tmp[3] = t[3];

                if (dist[tmp[0]][tmp[1]][tmp[2]][tmp[3]] > dist[t[0]][t[1]][t[2]][t[3]] + 1)
                {
                    dist[tmp[0]][tmp[1]][tmp[2]][tmp[3]] = dist[t[0]][t[1]][t[2]][t[3]] + 1;
                    q.push(tmp);
                }
            }
        }
    };
    bfs(st);
    ll ans = 1e9;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            if (a[i][j] == '.')
                ans = min(ans, dist[i][j][i][j]);
    if (ans == 1e9)
        ans = -1;
    cout << ans << endl;
}

E

线段树优化dp,维护转移范围内的最大值

struct node
{
    ll val;
};
struct segtree
{
    int n;
    vector<node> a;
    segtree(int _n) : n(_n * 4 + 10), a(n + 1) {}
    void update(int id) { a[id].val = max(a[id * 2].val, a[id * 2 + 1].val); }
    void build(int id, int l, int r, vector<int> &arr)
    {
        if (l == r)
            a[id].val = arr[l];
        else
        {
            int mid = l + r >> 1;
            build(id * 2, l, mid, arr);
            build(id * 2 + 1, mid + 1, r, arr);
            update(id);
        }
    }
    void change(int id, int l, int r, int pos, int val)
    {
        if (l == r) // 叶子节点
            a[id].val = val;
        else
        {
            int mid = l + r >> 1;
            if (pos <= mid)
                change(id * 2, l, mid, pos, val);
            else
                change(id * 2 + 1, mid + 1, r, pos, val);
            update(id);
        }
    }
    ll query(int id, int l, int r, int ql, int qr)
    {
        if (l == ql && r == qr)
            return a[id].val;
        int mid = l + r >> 1;
        if (qr <= mid)
            return query(id * 2, l, mid, ql, qr);
        else if (ql > mid)
            return query(id * 2 + 1, mid + 1, r, ql, qr);
        else
            return max(query(id * 2, l, mid, ql, mid), query(id * 2 + 1, mid + 1, r, mid + 1, qr));
    }
};
void solve()
{
    int n, d;
    cin >> n >> d;
    vector<int> a(n + 1), rec(N, 0);
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    segtree seg(N);
    seg.build(1, 1, n, rec);

    for (int i = 1; i <= n; i++)
    {
        int l = max(1, a[i] - d), r = min((int)5e5, a[i] + d);
        int res = seg.query(1, 1, N, l, r) + 1;
        int now = max(seg.query(1, 1, N, a[i], a[i]), 1ll);
        now = max(now, res);
        seg.change(1, 1, N, a[i], now);
    }
    ll res = 1;
    for (int i = 1; i <= n; i++)
        res = max(res, seg.query(1, 1, N, a[i], a[i]));
    cout << res << endl;
}

F

如果模数够大,够多,那么就可以保证\(a*b=c\)\(a%mod*b%mod=c%mod\)等效
可以双哈希,三哈希,或者模数开到ll
正经比赛的话,建议还是双哈希(

void solve()
{
    map<ll, ll> mp;
    int n;
    cin >> n;
    vector<ll> a(n + 1);
    auto cal = [&](string s) -> ll
    {
        ll res = 0;
        for (int i = 0; i < s.size(); i++)
            res = (res * 10 + (s[i] - '0')) % mod;
        return res;
    };
    for (int i = 1; i <= n; i++)
    {
        string s;
        cin >> s;
        a[i] = cal(s);
        mp[a[i]]++;
    }
    int ans = 0;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
        {
            ll tmp = __int128_t(a[i]) * a[j] % mod;
            ans += mp[tmp];
        }
    cout << ans << endl;
}

G

主席树模板题

#include <bits/stdc++.h>
#define endl '\n'
#define x first
#define y second
#define ls(x) (a[x].l)
#define rs(x) (a[x].r)
#define sum(x) a[x].sum
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef double db;
const ll mod = 1e9 + 7;
const int N = 7e7 + 10, M = 25;
random_device rd;
mt19937_64 gen(rd());
struct node
{
    ll sum, l, r;
};
struct segtree
{
    int n;
    vector<node> a;
    segtree(int _n) : n(1) { a.reserve(_n); }
    void update(int id)
    {
        sum(id) = sum(ls(id)) + sum(rs(id));
    }
    void build(int id, int l, int r)
    {
        if (l == r)
            sum(id) = 0;
        else
        {
            ls(id) = ++n, rs(id) = ++n;
            int mid = l + r >> 1;
            build(ls(id), l, mid);
            build(rs(id), mid + 1, r);
            update(id);
        }
    }
    void change(int pos, int l, int r, int id, int nxt, int val)
    {
        if (l == r)
        {
            sum(nxt) = sum(id) + val;
            return;
        }
        ls(nxt) = ls(id), rs(nxt) = rs(id);
        int mid = l + r >> 1;
        if (pos <= mid)
            ls(nxt) = ++n, change(pos, l, mid, ls(id), ls(nxt), val);
        else
            rs(nxt) = ++n, change(pos, mid + 1, r, rs(id), rs(nxt), val);
        update(nxt);
    }
    ll query(int id, int l, int r, int ql, int qr) // 查询某个版本的区间和
    {
        if (l == ql && r == qr)
            return sum(id);
        int mid = l + r >> 1;
        if (qr <= mid)
            return query(ls(id), l, mid, ql, qr);
        else if (ql > mid)
            return query(rs(id), mid + 1, r, ql, qr);
        else
            return query(ls(id), l, mid, ql, mid) + query(rs(id), mid + 1, r, mid + 1, qr);
    }
    ll query(int id, int nxt, int l, int r, int ql, int qr) // 在id-nxt版本之间查询值域在ql-qr的和
    {
        if (ql > qr)
            return 0;
        if (l == ql && r == qr)
            return sum(nxt) - sum(id);
        int mid = l + r >> 1;
        if (qr <= mid)
            return query(ls(id), ls(nxt), l, mid, ql, qr);
        else if (ql > mid)
            return query(rs(id), rs(nxt), mid + 1, r, ql, qr);
        else
            return query(ls(id), ls(nxt), l, mid, ql, mid) + query(rs(id), rs(nxt), mid + 1, r, mid + 1, qr);
    }
};

void solve()
{
    ll n, q, mx = 0;
    cin >> n;
    vector<ll> a(n + 1), b;
    for (int i = 1; i <= n; i++)
        cin >> a[i], b.push_back(a[i]), mx = max(mx, a[i]);

    sort(b.begin(), b.end());
    b.erase(unique(b.begin(), b.end()), b.end());
    cin >> q;
    vector<ll> root(n + 1);
    ll pre = 0;
    root[0] = 1;
    segtree seg(2e7);
    seg.build(root[0], 1, n);
    for (int i = 1; i <= n; i++)
    {
        root[i] = ++seg.n;
        int pos = (lower_bound(b.begin(), b.end(), a[i]) - b.begin()) + 1;
        seg.change(pos, 1, n, root[i - 1], root[i], a[i]);
    }
    for (int i = 1; i <= q; i++)
    {
        ll l, r, val;
        cin >> l >> r >> val;
        l ^= pre, r ^= pre, val ^= pre;
        int pos = (upper_bound(b.begin(), b.end(), val) - b.begin());
        pre = seg.query(root[l - 1], root[r], 1, n, 1, pos);
        cout << pre << endl;
    }
}
int main()
{
    // cout << setprecision(5);
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int _ = 1;
    // cin >> _;
    while (_--)
        solve();
    return 0;
}
posted @ 2024-02-07 22:16  0x3ea  阅读(9)  评论(0编辑  收藏  举报