• 欢迎光临~

Educational Codeforces Round 132 (Rated for Div. 2)

开发技术 开发技术 2022-07-21 次浏览

题目链接

A

B

题意

给一个数组 a[n], ai 为 i 处山的高度,可以在相邻两座山峰之间移动,如  ai-->a(i+1),

如果 ai>a(i+1),会受到伤害 ai - a(i+1),反之没有影响,给定两个点,问从一个点到另一个点受到的伤害最小为多少

思路

记录每两个点之间的伤害,再求前缀和即可,注意要从正反两边分别求两个前缀和数组

代码

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl "n"
const int N = 2e5 + 7, INF = 1e18;
int s[N], d1[N], d2[N];
void solve()
{
    int n, m;
    cin >> n >> m;
    s[0] = d1[0] = d2[0] = 0;
    d2[n + 1] = 0;
    for (int i = 1; i <= n; i++)
    {
        cin >> s[i];
        d1[i] = 0, d2[i] = 0;
    }
    for (int i = 1; i <= n; i++)
    {
        d1[i] += d1[i - 1];
        if (s[i] < s[i - 1])
            d1[i] += s[i - 1] - s[i];
    }
    for (int i = n; i >= 1; i--)
    {
        d2[i] += d2[i + 1];
        if (s[i] < s[i + 1])
            d2[i] += s[i + 1] - s[i];
    }
    for (int i = 1; i <= m; i++)
    {
        int a, b;
        cin >> a >> b;
        if (a < b)
        {
            cout << d1[b] - d1[a] << endl;
        }
        else
        {
            cout << d2[b] - d2[a] << endl;
        }
    }
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t = 1;
    // cin >> t;
    while (t--)
    {
        solve();
    }

    return 0;
}

 

C

题意

思路

代码

 

D

题意

有一个网格,由 n 行 m 列组成。行从下到上从 1 到 n 编号。列从左到右从 1 到 m 编号。第 i 列底部的 ai 个单元格被阻塞(第 1,2,...,ai 行中的单元格),剩余的 n−ai 个单元格未被阻塞。

一个机器人正在穿过这个网格。您可以向它发送命令——向上、向右、向下或向左移动。如果一个机器人试图进入一个被封锁的单元格或网格之外,它就会爆炸。

然而,机器人坏了——它执行每个收到的命令 k 次。因此,例如,如果您告诉它向上移动,它将向上移动 k 次(k 个单元格)。当机器人执行当前命令时,您无法向其发送命令。

您被问及有关机器人的 q 个问题。每个查询都有一个开始单元格、一个结束单元格和一个值 k。你能否向机器人发送任意数量的命令(可能为零),以便它从起始单元格到达终点单元格,假设它执行每个命令 k 次?

机器人必须停在终点单元。如果它在执行命令的同时访问完成单元格,则不算数。

思路

显然两点的横纵坐标之差必须为k的倍数。

找到两点之间的最高处,判断能否过去即可。

求最高点我用的是线段树(因为手边刚好有线段树模板

代码

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl "n"
const int N = 2e5 + 7, INF = 1e18;
int mid, n, ka, d[N];
struct D
{
    int l, r;
    int v;
} s[N * 4];
void bulid(int u, int l, int r)
{
    s[u] = {l, r};
    if (l == r)
    {
        s[u].v = d[l];
        return;
    }
    int mod = (l + r) >> 1;
    bulid(u << 1, l, mod), bulid(u << 1 | 1, mod + 1, r);
    s[u].v = max(s[u << 1].v, s[u << 1 | 1].v);
}

void add(int u, int x, int v)
{
    if (s[u].l == x && s[u].r == x)
    {
        s[u].v = v;
        return;
    }
    int mod = (s[u].l + s[u].r) >> 1;
    if (x <= mod)
        add(u << 1, x, v);
    else
        add(u << 1 | 1, x, v);
    s[u].v = max(s[u << 1].v, s[u << 1 | 1].v);
}
int fins(int u, int l, int r)
{
    if (s[u].l >= l && s[u].r <= r)
        return s[u].v;
    int cnt = 0;
    int mod = (s[u].l + s[u].r) >> 1;
    if (mod >= l)
        cnt = fins(u << 1, l, r);
    if (mod < r)
        cnt = max(cnt, fins(u << 1 | 1, l, r));
    return cnt;
}

void solve()
{
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= m; i++)
        cin >> d[i];
    bulid(1, 1, N);
    int t;
    cin >> t;
    while (t--)
    {
        int x1, y1, x2, y2, k;
        cin >> y1 >> x1 >> y2 >> x2 >> k;
        if (abs(x1 - x2) % k == 0 && abs(y1 - y2) % k == 0)
        {
            int sa = (n - y1) / k;
            y1 += k * sa;
            if (x1 > x2)
                swap(x1, x2);
            int fsa = fins(1, x1, x2);
            if (y1 > fsa)
            {
                cout << "YESn";
                continue;
            }
            else
            {
                cout << "NOn";
                continue;
            }
        }
        else
        {
            cout << "NOn";
            continue;
        }
    }
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    ;
    int _ = 1;
    // cin>>_;
    while (_--)
        solve();
}

 

程序员灯塔
转载请注明原文链接:Educational Codeforces Round 132 (Rated for Div. 2)
喜欢 (0)