Processing math: 100%

Codeforces

Codeforces #728

yujaa 2021. 7. 17. 18:40

A. Pretty Permutations

https://codeforces.com/contest/1541/problem/A

 

Problem - A - Codeforces

 

codeforces.com

n마리의 고양이가 일렬로 늘어서 있다.

i번째 고양이는 i번째 자리에 위치해 있다.

어떤 고양이도 이전에 있던 자리에 있지 않도록 자리를 바꿔야 한다.

 

1) n=2k

1in2, 2i1번째 고양이와 2i번째 고양이가 짝을 지어 자리를 바꾼다.

 

2) n=2k1

처음 3마리의 고양이끼리 자리를 바꾼다. [1, 2, 3] [3, 1, 2]

2in2, 2i번째 고양이와 2i+1번째 고양이가 짝을 지어 자리를 바꾼다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <bits/stdc++.h>
using namespace std;
 
int main(void) {
    cin.tie(NULL);
    ios::sync_with_stdio(false);
 
    int t; cin >> t;
    while (t--) {
        int n; cin >> n;
        if (n%2) {
            cout << 3 << ' ' << 1 << ' ' << 2 << ' ';
            for (int i = 2; i <= n/2; i++) {
                cout << 2*i+1 << ' ' << 2*<< ' ';
            }
        }
        else {
            for (int i = 1; i <= n/2; i++) {
                cout << 2*<< ' ' << 2*i-1 << ' ';
            }
        }
        cout << '\n';
    }
    return 0;
}
cs

 

 

 

B. Pleasant Pairs

https://codeforces.com/contest/1541/problem/B

 

Problem - B - Codeforces

 

codeforces.com

n개의 서로 다른 정수가 담긴 배열 a가 주어진다.

i<j이면서 aiaj=i+j인 인덱스 쌍 (i,j)의 개수를 구해야 한다.

 

aiaj=i+j이므로 ai|(i+j)이다.

j=aikij에 대해 aj=k인지 조사해보면 된다. (단, i<jn임을 주의)

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <bits/stdc++.h>
using namespace std;
 
int main(void) {
    cin.tie(NULL);
    ios::sync_with_stdio(false);
 
    int t; cin >> t;
    while (t--) {
        int n; cin >> n;
        vector<int> v(n+1);
        for (int i = 1; i <= n; i++) {
            cin >> v[i];
        }
        int ans = 0;
        for (int i = 1; i < n; i++) {
            for (int j = v[i]-i; j <= n; j += v[i]) {
                if (j <= i) continue;
                if (v[j] == (i+j)/v[i]) ans++;
            }
        }
        cout << ans << '\n';
    }
    return 0;
}

 

 

 

C. Great Graphs

https://codeforces.com/contest/1541/problem/C

 

Problem - C - Codeforces

 

codeforces.com

n개의 정점으로 이루어진 방향 그래프이다.

음의 간선이 존재할 수 있지만, 음의 사이클은 존재하지 않는다.

 

0번 정점으로부터 모든 정점들까지의 최소 거리(0di109)가 주어질 때,

그래프에 포함된 간선들의 가중치 합이 최소가 되도록 만들어야 한다.

 

이를 위해선 양의 간선의 가중치 합과 음의 간선의 가중치 합이 최소가 되도록 만들어야 한다.

0번 정점으로부터 거리가 가장 먼 정점을 a라고 하자.

양의 간선은 유일하게 (0,a) 하나만 존재한다.

모든 정점 u에 대해서, 정점 udv<du인 정점 v 사이에 간선 (u,v)를 추가한다.

이때 해당 간선의 가중치는 (dudv)이다.

 

간선의 가중치 합은 부분합 psum을 통해 구현할 수 있다.

음의 간선의 가중치들을의 절댓값을 나열해보면 다음과 같다.

a1a0

a2a0

a2a1

a3a0

a3a1

a3a2

규칙을 통해 이들의 합이 n1i=1{iaipsum[i1]}임을 알 수 있다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
 
int main(void) {
    cin.tie(NULL);
    ios::sync_with_stdio(false);
 
    int t; cin >> t;
    while (t--) {
        int n; cin >> n;
        vector<ll> v(n);
        for (int i = 0; i < n; i++) {
            cin >> v[i];
        }
        sort(v.begin(), v.end());
        
        vector<ll> psum(n);
        psum[0= 0;
        for (int i = 1; i < n; i++) {
            psum[i] = psum[i-1+ v[i];
        }
 
        ll ans = v.back();
        for (int i = 1; i < n; i++) {
            ans -= i*v[i];
            ans += psum[i-1];
        }
        cout << ans << '\n';
    }
    return 0;
}

 

 

 

D. Tree Array

https://codeforces.com/contest/1540/problem/B

 

Problem - B - Codeforces

 

codeforces.com

 

/* 풀이 추가 예정 */

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
 
int n;
const int MAX = 202;
const int MOD = 1e9 + 7;
 
vector<vector<int> > adj(MAX);
int depth[MAX];
int par[MAX][8];
int dp[MAX][MAX];
 
void makeTree(int cur) {
    for (int nxt: adj[cur]) {
        if (depth[nxt] == -1) {
            depth[nxt] = depth[cur] + 1;
            par[nxt][0= cur;
            makeTree(nxt);
        }
    }
}
 
int lca(int u, int v) {
    if (depth[u] < depth[v]) swap(u, v);
    int diff = depth[u] - depth[v];
    for (int i = 0; i < 8; i++) {
        if (diff & (1 << i)) u = par[u][i];
    }
    if (u != v) {
        for (int i = 7; i >= 0; i--) {
            if (par[u][i] != -1 && par[u][i] != par[v][i]) {
                u = par[u][i];
                v = par[v][i];
            }
        }
        u = par[u][0];
    }
    return u;
}
 
int modPow(int a, int k) {
    if (k == 0) return 1;
    ll ret = modPow(a, k/2);
    ret = (ret * ret) % MOD;
    if (k%2) return (ret * a) % MOD;
    else return ret;
}
 
int f(int a, int b) {
    if (dp[a][b] != -1) return dp[a][b];
    if (a == 0) return 0;
    if (b == 0) return 1;
    ll ret = ((ll)f(a-1, b) + f(a, b-1)) % MOD;
    return dp[a][b] = (ret * modPow(2, MOD-2)) % MOD;
}
 
int main(void) {
    cin.tie(NULL);
    ios::sync_with_stdio(false);
 
    cin >> n;
    for (int i = 1; i < n; i++) {
        int u, v;
        cin >> u >> v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
 
    ll ans = 0;
    for (int i = 1; i <= n; i++) {
        memset(depth, -1, sizeof depth);
        for (int j = 0; j < MAX; j++) {
            for (int k = 0; k < 8; k++) {
                par[j][k] = -1;
            }
        }
        depth[i] = 0; par[i][0= -1;
        makeTree(i);
        for (int k = 1; k < 8; k++) {
            for (int j = 1; j <= n; j++) {
                if (par[j][k-1!= -1)
                    par[j][k] = par[par[j][k-1]][k-1];
            }
        }
 
        for (int j = 0; j < MAX; j++) {
            for (int k = 0; k < MAX; k++) {
                dp[j][k] = -1;
            }
        }
 
        ll tmp = 0;
        for (int j = 1; j <= n; j++) {
            for (int k = j+1; k <= n; k++) {
                int l = lca(j, k);
                int da = depth[j] - depth[l];
                int db = depth[k] - depth[l];
                tmp = (tmp + f(da, db)) % MOD;
            }
        }
        tmp *= modPow(n, MOD-2);
        tmp %= MOD;
 
        ans += tmp;
        ans %= MOD;
    }
    cout << ans;
    return 0;
}
cs

'Codeforces' 카테고리의 다른 글

Codeforces #763  (0) 2022.01.02
Codeforces Educational #120  (0) 2022.01.02
Codeforces Global #18  (0) 2021.12.26
Codeforces Educational #82  (0) 2021.12.26
Codeforces #619  (0) 2021.12.23