1. 程式人生 > >Codeforces Round #475 Div. 2 A B C D

Codeforces Round #475 Div. 2 A B C D

rac sca 節點 spa AR 並且 split -s using

A - Splits

題意

將一個正整數拆分成若幹個正整數的和,從大到小排下來,與第一個數字相同的數字的個數為這個拆分的權重。

\(n\)的所有拆分的不同權重可能個數。

思路

全拆成1,然後每次將2個1換成1個2,即每次2的個數增加1。

共有1+n/2種。

Code

#include <bits/stdc++.h>
#define F(i, a, b) for (int i = (a); i < (b); ++i)
#define F2(i, a, b) for (int i = (a); i <= (b); ++i)
#define dF(i, a, b) for (int i = (a); i > (b); --i)
#define dF2(i, a, b) for (int i = (a); i >= (b); --i) using namespace std; typedef long long LL; int main() { int n; scanf("%d", &n); printf("%d\n", n/2+1); return 0; }

B - Messages

題意

收到報文的時刻報文價值為A,之後每秒其價值減少B。在某個時刻讀某個報文即能得到該報文此時的價值;此外,每秒能獲得的固定收益為當前報文數*C.

問最大收益。

思路

理解題意即可:每個報文的價值,即每秒減少B,增加C。

因此只需比較B與C,如果B大,則所有報文都收到立即讀;否則全都堆到最後讀。

Code

#include <bits/stdc++.h>
#define F(i, a, b) for (int i = (a); i < (b); ++i)
#define F2(i, a, b) for (int i = (a); i <= (b); ++i)
#define dF(i, a, b) for (int i = (a); i > (b); --i)
#define dF2(i, a, b) for (int i = (a); i >= (b); --i)
using namespace std; typedef long long LL; int main() { int n,a,b,c,T; scanf("%d%d%d%d%d",&n,&a,&b,&c,&T); int x, sum=0; F(i, 0, n) scanf("%d", &x), sum += x; LL ans = n*a; if (c>b) ans += 1LL*(c-b)*(n*T-sum); printf("%d\n", ans); return 0; }

C - Alternating Sum

題意

計算\(\sum \limits_{i=0}^{n} s_{i} a^{n - i} b^{i}\),其中系數\(s\)只取\(\pm1\),且為周期函數,周期為\(T=\frac{n+1}{k}\).

思路

即計算\(\sum \limits_{i=0}^{k-1} s_{i} a^{n - i} b^{i}\cdot\frac{q^{\frac{n+1}{k}}-1}{q-1}\),註意特判\(q=1\).

Code

#include <bits/stdc++.h>
#define F(i, a, b) for (int i = (a); i < (b); ++i)
#define F2(i, a, b) for (int i = (a); i <= (b); ++i)
#define dF(i, a, b) for (int i = (a); i > (b); --i)
#define dF2(i, a, b) for (int i = (a); i >= (b); --i)
using namespace std;
typedef long long LL;
const LL mod = 1e9+9;
LL poww(LL a, LL b) {
    LL ret = 1;
    while (b) {
        if (b & 1) (ret *= a) %= mod;
        (a *= a) %= mod;
        b >>= 1;
    }
    return ret;
}
inline LL mul(LL a, LL b) { return a * b % mod; }
inline LL add(LL a, LL b) { return (a+b+mod) % mod; }
#define maxn 100010
char s[maxn];
int main() {
    int n, a, b, k;
    scanf("%d%d%d%d", &n, &a, &b, &k);
    scanf("%s", s);
    LL aa = poww(a, n), bb = 1, inva = poww(a, mod-2), ans = 0;
    F(i, 0, k) {
        int sign = s[i]=='+' ? 1 : -1;
        ans = add(ans, sign*mul(aa, bb));
        aa = mul(aa, inva);
        bb = mul(bb, b);
    }
    LL q = mul(poww(b, k), poww(inva, k));
    int cnt = (n+1) / k;
    if (q == 1) ans = mul(ans, cnt);
    else ans = mul(ans, mul(poww(q, cnt)-1, poww(q-1, mod-2)));
    printf("%I64d\n", ans);
    return 0;
}

D - Destruction of a Tree

題意

在樹上刪點,當且僅當該點的度數為偶數時才能刪去,問能否刪完圖中所有點,並要求給出操作序列。

思路

從葉子開始從下往上考慮,顯然葉子不能直接刪,要刪葉子必然要在刪去其父親節點之後進行。

而其父親能不能直接刪呢?如果其有奇數個孩子(未被刪去的),則可以直接刪去該節點(因其關聯的邊為連向其奇數個孩子+其父親的共偶數條邊),然後再向下刪去之前未刪去的部分;否則,其的刪除工作必然要留到其父親被刪除之後才能進行。(註意,葉子節點也是符合這個特性的,因為葉子節點的孩子數0為偶數)

因此,dfs,從下往上考慮每個節點有多少個孩子未被刪去;若為奇數個,則可刪去該節點(並一路往下刪孩子),並且忽略該節點對其父親節點度數的貢獻;否則,繼續一路向上。

Code

#include <bits/stdc++.h>
#define F(i, a, b) for (int i = (a); i < (b); ++i)
#define F2(i, a, b) for (int i = (a); i <= (b); ++i)
#define dF(i, a, b) for (int i = (a); i > (b); --i)
#define dF2(i, a, b) for (int i = (a); i >= (b); --i)
#define maxn 200010
using namespace std;
typedef long long LL;
struct Edge {
    int to, ne;
}edge[maxn<<1];
int ne[maxn], tot, rt;
bool flag[maxn];
vector<int> ans;
void add(int u, int v) {
    edge[tot] = {v, ne[u]};
    ne[u] = tot++;
}
void collect(int u, int fa) {
    ans.push_back(u);
    flag[u] = true;
    for (int i = ne[u]; ~i; i = edge[i].ne) {
        int v = edge[i].to;
        if (v == fa || flag[v]) continue;
        collect(v, u);
    }
}
int dfs(int u, int fa) {
    int tot = 0;
    for (int i = ne[u]; ~i; i = edge[i].ne) {
        int v = edge[i].to;
        if (v == fa) continue;
        tot += dfs(v, u);
    }
    if ((u==rt&&!(tot&1)) || (u!=rt&&tot&1)) collect(u, fa);
    return !(tot&1);
}
int main() {
    memset(ne, -1, sizeof ne);
    int n, x;
    scanf("%d", &n);
    F2(i, 1, n) {
        scanf("%d", &x);
        if (!x) rt = i;
        else add(i, x), add(x, i);
    }
    if (dfs(rt, -1)) {
        puts("YES");
        for (auto x : ans) printf("%d\n", x);
    }
    else puts("NO");
    return 0;
}

Codeforces Round #475 Div. 2 A B C D