AtCoder Beginner Contest 188

ABC都很水

D

很裸的差分题

#include <bits/stdc++.h>
#define IO                       \
    ios::sync_with_stdio(false); \
    // cin.tie(0);                  \
    // cout.tie(0);
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int maxn = 4e5 + 100;
const int maxm = 1e6 + 10;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const LL mod = 1e9 + 7;
// int dis[8][2] = {0, 1, 1, 0, 0, -1, -1, 0, 1, -1, 1, 1, -1, 1, -1, -1};
struct Node
{
    int x;
    LL val;
} a[maxn];
LL c;
int n;
bool cmp(Node a, Node b)
{
    return a.x < b.x;
}
int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("in.txt", "r", stdin);
    // freopen("out.txt", "w", stdout);
#endif
    IO;
    int t1, t2;
    LL t3;
    cin >> n >> c;
    for (int i = 1; i <= 2 * n; i += 2)
    {
        cin >> t1 >> t2 >> t3;
        a[i].x = t1, a[i].val = t3;
        a[i + 1].x = t2 + 1, a[i + 1].val = -t3;
    }
    sort(a + 1, a + 2 * n + 1, cmp);
    LL ans = 0;
    LL s = 0;
    for (int i = 1; i <= (n << 1); i++)
    {
        ans += min(c, s) * (a[i].x - a[i - 1].x);
        s += a[i].val;
    }
    cout << ans;
    return 0;
}

E

拓扑排序过程中维护当前点之前的最小值,然后和当前点取差维护答案

#include <bits/stdc++.h>
#define IO                       \
    ios::sync_with_stdio(false); \
    // cin.tie(0);                  \
    // cout.tie(0);
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int maxn = 2e5 + 100;
const int maxm = 1e6 + 10;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const LL mod = 1e9 + 7;
// int dis[8][2] = {0, 1, 1, 0, 0, -1, -1, 0, 1, -1, 1, 1, -1, 1, -1, -1};
struct Edge
{
    int next, to;
} e[maxn << 2];
int head[maxn];
LL a[maxn];
LL dp[maxn];
LL ans = -2 * mod;
int in[maxn];
int n, m;
int k = 0;

void add(int u, int v)
{
    e[k].next = head[u];
    e[k].to = v;
    head[u] = k++;
}
void topo()
{
    queue<int> q;
    for (int i = 1; i <= n; i++)
        if (in[i] == 0)
        {
            q.push(i);
        }
    while (!q.empty())
    {
        int u = q.front();
        q.pop();
        if (a[u] - dp[u] > ans)
            ans = a[u] - dp[u];
        for (int i = head[u]; ~i; i = e[i].next)
        {
            int v = e[i].to;
            dp[v] = min(dp[v], min(dp[u], a[u]));
            in[v]--;
            if (in[v] == 0)
                q.push(v);
        }
    }
    return;
}
int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("in.txt", "r", stdin);
    // freopen("out.txt", "w", stdout);
#endif
    IO;
    int x, y;
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        head[i] = -1;
        dp[i] = 1e10;
    }
    for (int i = 0; i < m; i++)
    {
        cin >> x >> y;
        add(x, y);
        in[y]++;
    }
    topo();
    cout << ans;
    return 0;
}

F

从Y到X进行BFS,如果当前点一定不能更新答案则可以退出循环停止搜索,如果超出搜索范围则进行剪枝,需要注意当前的数是否%2==0

#include <bits/stdc++.h>
#define IO                       \
    ios::sync_with_stdio(false); \
    // cin.tie(0);                  \
    // cout.tie(0);
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int maxn = 2e5 + 100;
const int maxm = 1e6 + 10;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const LL mod = 1e9 + 7;
// int dis[8][2] = {0, 1, 1, 0, 0, -1, -1, 0, 1, -1, 1, 1, -1, 1, -1, -1};
struct Node
{
    LL val;
    int dep;
    Node() {}
    Node(LL x, int y)
    {
        val = x, dep = y;
    }
};
map<LL, bool> mp;
LL x, y;
LL BFS()
{
    queue<Node> q;
    q.push(Node(y, 0));
    LL ans = y - x;
    while (!q.empty())
    {
        Node now = q.front();
        q.pop();
        if (now.dep >= ans)
            break;
        ans = min(ans, now.dep + abs(now.val - x));
        if (now.val <= x)
            continue;
        if (now.val % 2 == 0)
        {
            if (mp[now.val / 2] == false)
            {
                mp[now.val / 2] = true;
                q.push(Node(now.val / 2, now.dep + 1));
            }
        }
        else
        {
            if (mp[now.val + 1] == false)
            {
                mp[now.val + 1] = true;
                q.push(Node(now.val + 1, now.dep + 1));
            }
            if (mp[now.val - 1] == false)
            {
                mp[now.val - 1] = true;
                q.push(Node(now.val - 1, now.dep + 1));
            }
        }
    }
    return ans;
}
int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("in.txt", "r", stdin);
    // freopen("out.txt", "w", stdout);
#endif
    IO;
    cin >> x >> y;
    if (x >= y)
        cout << x - y;
    else
        cout << BFS();
    return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值