首页 > 其他分享 >Codeforces Round #875 (Div. 2) A-D

Codeforces Round #875 (Div. 2) A-D

时间:2023-07-16 19:00:13浏览次数:44  
标签:pre int 875 Codeforces len leq long using Div

比赛链接

A

代码

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

bool solve() {
    int n;
    cin >> n;
    for (int i = 1;i <= n;i++) {
        int x;
        cin >> x;
        cout << n - x + 1 << " \n"[i == n];
    }
    return true;
}

int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--) {
        if (!solve()) cout << -1 << '\n';
    }
    return 0;
}

B

代码

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

int lena[400007], lenb[400007];
bool solve() {
    int n;
    cin >> n;
    for (int i = 1;i <= 2 * n;i++) lena[i] = lenb[i] = 0;
    int pre = 0, len = 0;
    for (int i = 1;i <= n;i++) {
        int x;
        cin >> x;
        if (x != pre) {
            lena[pre] = max(lena[pre], len);
            len = 0;
            pre = x;
        }
        len++;
    }
    lena[pre] = max(lena[pre], len);
    len = 0;
    pre = 0;
    for (int i = 1;i <= n;i++) {
        int x;
        cin >> x;
        if (x != pre) {
            lenb[pre] = max(lenb[pre], len);
            len = 0;
            pre = x;
        }
        len++;
    }
    lenb[pre] = max(lenb[pre], len);
    int ans = 0;
    for (int i = 1;i <= 2 * n;i++) ans = max(ans, lena[i] + lenb[i]);
    cout << ans << '\n';
    return true;
}

int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--) {
        if (!solve()) cout << -1 << '\n';
    }
    return 0;
}

C

题意

一棵树有 \(n\) 个节点,一开始只有根节点 \(1\) 。

现在给出加边的顺序,每次操作按顺序从头到尾依次加边。

一次操作中,当且仅当一条边还没被加,且一个端点已经存在,才能加这条边。

问要最少操作几次,所有边才能都被加入。

题解

知识点:树形dp,DFS。

可以用树型dp求出每个点出现需要的最少操作次数。

点的出现时间取决于边的顺序,我们将边的顺序记录到边权中,dfs过程中将边权当作孩子的出现时间。

若一个点出现时间比它孩子出现时间要晚,那么它孩子出现需要的操作次数就是它的操作次数加 \(1\) ,否则可以在同一次操作中处理完。

设 \(f_u\) 表示节点 \(u\) 出现需要的最少操作次数, \(rk_u\) 表示节点 \(u\) 的出现时间,转移即上述所说。

最后答案为 \(f_u\) 的最大值。

时间复杂度 \(O(n)\)

空间复杂度 \(O(n)\)

代码

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

vector<pair<int, int>> g[200007];

int rk[200007], f[200007];
void dfs(int u, int fa) {
    for (auto [v, w] : g[u]) {
        if (v == fa) continue;
        rk[v] = w;
        f[v] = f[u] + (w < rk[u]);
        dfs(v, u);
    }
}

bool solve() {
    int n;
    cin >> n;
    for (int i = 1;i <= n;i++) g[i].clear();
    for (int i = 1;i <= n - 1;i++) {
        int u, v;
        cin >> u >> v;
        g[u].push_back({ v,i });
        g[v].push_back({ u,i });
    }

    rk[1] = n;
    dfs(1, 0);

    cout << *max_element(f + 1, f + n + 1) << '\n';
    return true;
}

int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--) {
        if (!solve()) cout << -1 << '\n';
    }
    return 0;
}

D

题意

给定长度为 \(n\) 的数组 \(a,b\) ,求出所有满足 \(a_i \cdot a_j = b_i + b_j (1 \leq i<j \leq n)\) 的 \((i,j)\) 对数。

题解

知识点:数学,枚举。

注意到 \(1 \leq a_i,b_i \leq n (1\leq i \leq n)\) ,因此 \(a_i \cdot a_j \leq 2n\) ,即 \(\min(a_i,a_j) \leq \sqrt{2n}\) 。此时,我们设 \(a_j \leq a_i\) ,那么 \(a_j \leq \sqrt{2n}\) 。

因此,我们先将 \(a_i,b_i\) 打包,以 \(a\) 为关键字从小到大排序,这是为了之后从左到右枚举 \(a_i,b_i\) 时,保证满足 \(a_j \leq a_i(1 \leq j < i)\) 这个条件,此时 \(a_j\) 的范围才是 \([1,\sqrt{2n}]\) 。

随后,我们枚举 \(A \in [1,\sqrt{2n}]\) ,作为一轮枚举中 \(a_j\) 满足的值。接下来,从左到右枚举 \(a_i,b_i\) ,有 \(B = A \cdot a_i - b_i\) ,其中 \(B\) 就是在 \(a_j = A\) 时我们希望的 \(b_j\) ,而 \(a_i,b_i\) 的贡献即为 \(1 \leq j <i\) 满足 \(a_j = A\) 的位置中,出现过的 \(b_j = B\) 的位置数。

因此,我们在过程中记录 \(1 \leq j <i\) 满足 \(a_j = A\) 的位置中,出现过的 \(b_j\) 的个数 \(cnt_{b_j}\)。那么,当 \(1 \leq B \leq n\) 时, \(cnt_B\) 即为 \(a_i,b_i\) 的贡献。

时间复杂度 \(O(n \sqrt n)\)

空间复杂度 \(O(n)\)

代码

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

pair<int, int> c[200007];
bool solve() {
    int n;
    cin >> n;
    for (int i = 1;i <= n;i++)cin >> c[i].first;
    for (int i = 1;i <= n;i++)cin >> c[i].second;
    sort(c + 1, c + n + 1);

    ll ans = 0;
    for (int A = 1;A * A <= 2 * n;A++) {
        vector<int> cnt(n + 1);
        for (int i = 1;i <= n;i++) {
            auto [a, b] = c[i];
            int B = A * a - b;
            if (1 <= B && B <= n) ans += cnt[B];
            if (a == A) cnt[b]++;
        }
    }
    cout << ans << '\n';
    return true;
}

int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--) {
        if (!solve()) cout << -1 << '\n';
    }
    return 0;
}

标签:pre,int,875,Codeforces,len,leq,long,using,Div
From: https://www.cnblogs.com/BlankYang/p/17558351.html

相关文章

  • Codeforces Round 884
    目录写在前面ABCDEF1F2学到了什么写在前面比赛地址:https://codeforces.com/contest/1844。什么?你怎么知道我连C都没过掉了一伯伍拾昏?吐槽一下马娘前期甚至动画第一季都没出之前的很多个人角色曲,听起来就是很无聊的动漫op风。比如进王的这首:感觉给哪个笨蛋阳光系角色都能......
  • Educational Codeforces Round 137 (Rated for Div. 2)
    EducationalCodeforcesRound137(RatedforDiv.2) A.Passwordvoidsolve(){intn=read();for(inti=1;i<=n;i++)intx=read();cout<<combination(10-n,2)*6<<'\n';//puts(ans>0?"YES":"NO");......
  • Codeforces Round #881 (Div. 3) A-F
    比赛链接A代码#include<bits/stdc++.h>usingnamespacestd;usingll=longlong;inta[57];boolsolve(){intn;cin>>n;for(inti=1;i<=n;i++)cin>>a[i];sort(a+1,a+n+1);intsum=0;for(inti......
  • Codeforces Round 881 (Div. 3) D - Apple Tree(dfs)
    https://codeforces.com/contest/1843/problem/D题目大意:一颗树中,每次给定两个结点,每个结点都可以移动到孩子结点,最后可以到达叶子结点,问我们这两个结点最终移到叶子结点有多少种组合?(其实就是让求以这两个节点为根的子树的叶子结点个数的乘积)input2512345332......
  • How to ak 【LGR-145-Div.4】洛谷入门赛 #14?
    A数字判断#include<bits/stdc++.h>#include<ext/pb_ds/assoc_container.hpp>#include<ext/pb_ds/tree_policy.hpp>#include<ext/pb_ds/hash_policy.hpp>#definereregister#definelll__int128#definegcgetchar#defineptputchar#definei......
  • Codeforces Round 875 (Div. 2)
    CodeforcesRound875(Div.2)A-TwinPermutations思路:让序列全相等为n+1即可#include<bits/stdc++.h>usingnamespacestd;typedefpair<int,int>PII;typedefpair<string,int>PSI;typedefpair<string,string>PSS;constintN=2e5+5,INF=0x3f3f......
  • Codeforces Round 884 (Div. 1 + Div. 2)
    CodeforcesRound884(Div.1+Div.2) A-SubtractionGame思路:显而易见为a+b#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongtypedefpair<int,int>PII;typedefpair<string,int>PSI;typedefpair<string,string>PSS;c......
  • Atcoder Regular Contest 114 F - Permutation Division
    显然分成\(k\)段以后,最大化形成的排列的字典序的策略是将所有段按第一个元素的大小降序排列。由于最终排列的字典序肯定\(\ge\)原排列的字典序,因此我们考虑最大化最终排列与原排列的LCP,这部分就考虑二分答案,记\(dp_i\)表示以\(p_1\)开始\(p_i\)结尾的LDS的长度,那么......
  • 教你快速掌握两个div在同一行显示css如何实现
    我们都知道div是一个块元素,块元素的特点是,独占一行,从上往下排列,但是有时候我们在页面排版的时候需要从左往右横着排列,想要实现这样的效果方法有很多,首先先来看一下,默认情况下的2个div的效果如下代码如下:<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF......
  • Codeforces 1396E - Distance Matching
    先考虑一下合法的\(k\)的上界和下界是什么以及如何达到上界和下界,我们找出树的一个重心\(R\)并以\(R\)为根dfs一遍整棵树,那么:下界为\(\sum(siz_i\bmod2)\),构造方法是从下往上钦定,对于一个点考虑其所有没有匹配的儿子,如果是偶数个就将它们两两匹配,如果是奇数个就将它们......