Codeforces Round #611 (Div. 3)

# Name
A Minutes Before the New Year standard input/output1 s, 256 MB
B Candies Division standard input/output2 s, 256 MB
C Friends and Gifts standard input/output2 s, 256 MB
D Christmas Trees standard input/output2 s, 256 MB
E New Year Parties standard input/output2 s, 256 MB
F DIY Garland standard input/output2 s, 256 MB

总结

6/6 unofficial rank 42

题目很简单而且有些锅(描述以及spj),虽然赛后才修好C的judge,但是还是rated了。

A

h:m,求到0:0还有多少分钟

\[res=(24-h)\cdot60-m \]

B

n个物品分给k个人,要求每个人的差不超过1且大一点的人数不超过总人数一半。

大部分人可以取到\(n/k\)个物品,小部分是\(n/k+1\)

答案为\(\min((k - k / 2) * (n / k) + (k / 2) * (n / k + 1), n)\)

C

n个点连n条有向边使得他们成环,已经给出一些边。

简单来说是一些链和一些点,使得他们成环即可,链的终点特性的入度为1没有出度。成环的方法是首尾相接。

D

有n+m个不同一维坐标整点,给出其中n个记做a集合,求构造m个使得这m个在a集合中最近的点距离和最小。

输出距离和构造的点坐标。

显然类似bfs即可,用map做vis标记。

E

有n个整数,表示坐标轴上n个点,定义一个序列的值为他们占用的不同位置的数量。对其中每个数x可以选择x-1,x,x+1三种,求序列最小值和最大值。

对最小值可以dp求解,只需要判断每个点前两个的关系即可,最大值直接贪心优先放在-1位置,如果已经放过了放在本身,再放过了放在+1就可以了。

F

构造一棵有根树,有点权,\(i\)点的点权为\(2^{i}\),定义一个边的权为割掉这条边会丢失的点权,其中丢失的部分是原理根节点的部分,给出n-1条边中靠近根节点的点下标,保证给出的边是按边权大到小排序的,求原树的形状。

首先对没有出度的点进行排序,已知没有出度的点必是叶子节点且他们构造的点权必是最小的一批,按边权从小到大倒塞回去,构成逆拓扑序,如果一个节点被塞到度为0了则把它也加入队列,此时产生了一个权值排序的问题,由于一个点如果没有出度,它的权值以及它对父亲节点的贡献是固定的,所以可以对这个用优先队列维护拓扑,权值为子树的最大点。因为点权为\(2^i\),无论如何选择,对一个集合\(a:\{x_1, x_2 \dots, x_n\}\)和另一个集合\(b:\{y_1,y_2,\dots, y_m\}\),如果\(\max(x_i)>max(y_i)\),a集合贡献总是比b大,所以可以对每一个点维护一个子树最大值。然后就可以解出所有的边了。

代码:

/*================================================================
*   Copyright (C) 2019 Sangfor Ltd. All rights reserved.
*
*   创 建 者: badcw
*   创建日期: 2019/12/29
*
================================================================*/
#include <bits/stdc++.h>

#define ll long long
using namespace std;

const int maxn = 2e5+50;
const int mod = 1e9+7;
ll qp(ll a, ll n) {
    ll res = 1;
    while (n > 0) {
        if (n & 1) res = res * a % mod;
        a = a * a % mod;
        n >>= 1;
    }
    return res;
}

template <class T>
inline bool scan(T& ret) {
    char c;
    int sgn;
    if (c = getchar(), c == EOF) return 0; // EOF
    while (c != '-' && (c < '0' || c > '9')) c = getchar();
    sgn = (c == '-') ? -1 : 1;
    ret = (c == '-') ? 0 : (c - '0');
    while (c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0');
    ret *= sgn;
    return 1;
}

//template <class T>
//inline void out(T x) {
//    if (x > 9) out(x / 10);
//    putchar(x % 10 + '0');
//}

int n;
int deg[maxn];
int pos[maxn];
int a[maxn];
struct node {
    int x;
    bool operator < (const node& oth) const {
        return pos[x] > pos[oth.x];
    }
};

int main(int argc, char* argv[]) {
    scanf("%d", &n);
    for (int i = 1; i < n; ++i) {
        int x;
        scanf("%d", &x);
        a[i] = x;
        deg[x] ++;
    }
    for (int i = 1; i <= n; ++i) pos[i] = i;
    priority_queue<node> qu;
    for (int i = 1; i <= n; ++i) {
        if (!deg[i]) {
            qu.push({i});
        }
    }
    printf("%d\n", a[1]);
    for (int i = n - 1; i >= 1; --i) {
        printf("%d %d\n", a[i], qu.top().x);
        pos[a[i]] = max(pos[a[i]], qu.top().x);
        qu.pop();
        deg[a[i]] --;
        if (deg[a[i]] == 0) {
            qu.push({a[i]});
        }
    }
    return 0;
}
posted @ 2019-12-30 02:51  badcw  阅读(142)  评论(0编辑  收藏  举报