AtCoder Beginner Contest 252(D - Distinct Trio & E - Road Reduction & F - Bread)

比赛链接

AtCoder Beginner Contest 252

D - Distinct Trio

原题链接

D - Distinct Trio

题面

在这里插入图片描述

思路

  • 给你一个序列,求三元组得个数,因为要找三个数字,直接求的话显然复杂度不行,我们可以把中间数字 A j A_j Aj固定,求有多少个数字比 A j A_j Aj小,有多少个数字比$A_j大,就是可以统计每一个数字出现的次数,然后求前缀和即可。

代码

const int N = 2e5+100;
void solve(){
    int n; cin >> n;
    vector<int> a(n), s(N);
    for(int i = 0; i < n; i++) {
        cin >> a[i];
        s[a[i]] ++;
    }

    sort(all(a));
    a.erase(unique(all(a)), a.end());
    for(int i = 1; i < N; i++) s[i] += s[i - 1];

    ll ans = 0;
    for(int i = 0; i < a.size(); i++) {
        ans += 1ll * s[a[i] - 1] * (n - s[a[i]]) * (s[a[i]] - s[a[i] - 1]);
        // 比Aj小的 * 比Aj大的 * Aj个数
    }

    cout << ans << '\n';
}

E - Road Reduction

原题链接

E - Road Reduction

题面

在这里插入图片描述

思路

  • n个点m条边,从1号点开始到第i个点的最短距离为 d i d_i di,求 d 2 + d 3 + . . . + d n d_2+d_3+...+d_n d2+d3+...+dn最小值,最短路生成树。首先题目保证图是联通的,从1好点开始跑一个dijksra求出从1号点到每个点的最短距离,然后将连接这些点的边输出。

代码

const int N = 2e5+100;
int h[N], id[N * 2], e[N * 2], ne[N * 2], w[N * 2];
ll dist[N], idx;
void add(int a, int b, int c, int d) {
    e[idx] = b, id[idx] = d, w[idx] = c, ne[idx] = h[a], h[a] = idx ++;
}
bool vis[N];
void solve(){
    memset(h, -1, sizeof h);
    int n, m; cin >> n >> m;
    for(int i = 1; i <= m; i++) {
        int a, b, c; cin >> a >> b >> c;
        add(a, b, c, i); add(b, a, c, i);
    }
 
    function<void()> dijkstra = [&](){
        memset(dist, 0x3f, sizeof dist);
        dist[1] = 0;
        priority_queue<pair<ll, int>> pq;
        pq.push({0, 1});
 
        while(pq.size()) {
            auto t = pq.top().second; pq.pop();
 
            if(vis[t]) continue;
            vis[t] = 1;
 
            for(int i = h[t]; ~i; i = ne[i]) {
                int j = e[i];
                if(dist[j] > dist[t] + w[i]) {
                    dist[j] = dist[t] + w[i];
                    pq.push({-dist[j], j});
                }
            }
        }
    };
 
    dijkstra();
 
    for(int u = 2; u <= n; u++) {
        for(int i = h[u]; ~i; i = ne[i]) {
            int j = e[i];
            if(dist[u] == dist[j] + w[i]) {
                cout << id[i] << ' ';
                break;
            }
        }
    }
}

F - Bread

原题链接

F - Bread

题面

在这里插入图片描述

思路

  • 每次分割完面包后代价是分割前的长度,想到合并果子那题类似,详细看下面代码。

代码

void solve(){
    ll n, l; cin >> n >> l;
    priority_queue<ll, vector<ll>, greater<ll>> pq;
    for(int i = 0; i < n; i++) {
        int u; cin >> u;
        pq.push(u);
        l -= u;
    }
    if(l) pq.push(l);
    ll ans = 0;
    while(pq.size() > 1) {
        auto l = pq.top(); pq.pop();
        auto r = pq.top(); pq.pop();
        ans += l + r;
        pq.push(l + r);
    }
    cout << ans << '\n';
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: atcoder beginner contest 252 是一场由 AtCoder 组织的初级比赛,旨在为初学者提供一个练习和展示自己的平台。比赛通常包括多个问题,涵盖算法和数据结构等方面的知识。参赛者需要在规定时间内解决尽可能多的问题,以获得最高的排名。这场比赛对于想要提高编程技能和参加 AtCoder 竞赛的人来说是一个很好的起点。 ### 回答2: atcoder beginner contest 252是一场由atcoder组织的初级比赛。该比赛旨在提供给初学者一个展示自己编程技能的平台,并帮助他们提高编程水平。 比赛中的问题通常涵盖了各种编程难度级别,从简单的问题到较难的问题都有。选手们需要通过编写算法和代码解决这些问题。 在比赛开始前,选手们会收到一系列的问题描述。问题描述中包含了输入数据和所需输出的格式。选手们需要根据这些信息,设计合适的算法来解决问题。 比赛的规则非常严格,选手只有在规定的时间内才能提交代码。在提交代码后,系统会自动运行选手编写的程序,并对结果进行评判。选手的得分将根据他们的代码正确性和运行时间来评定。 参加atcoder beginner contest 252对于初学者来说是一个很好的学习和锻炼的机会。通过解决比赛中的问题,选手们能够巩固所学的知识,并学会应用它们解决实际问题。 此外,比赛过程中选手们还可以通过与其他参赛选手交流、讨论解题思路来互相学习和提高。 总而言之,atcoder beginner contest 252是一个能够测试初学者编程能力的比赛,参与其中有助于提高编程技能并与其他编程爱好者交流经验。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值