Educational Codeforces Round 7
Educational Codeforces Round 7
https://codeforces.com/contest/622/problems
3/6: ABD
A. Infinite Sequence
水题
#include <bits/stdc++.h>
using namespace std;
int main () {
long long x;
cin >> x;
long long n = sqrt (2 * x), m = (n + 1) * n / 2;
//cout << m << ' ';
if (x <= m) {
cout << n - (m - x);
}
else {
cout << x - m;
}
}
B. The Time
水题
#include <bits/stdc++.h>
using namespace std;
int main () {
int hh, mm, dx;
scanf ("%d:%d", &hh, &mm);
scanf ("%d", &dx);
//cout << hh << ' ' << mm << ' ' << dx << endl;
mm += dx;
hh += mm / 60, mm %= 60, hh %= 24;
//cout << hh << ' ' << mm;
cout << setw(2) << setfill('0') << hh << ':';
cout << setw(2) << setfill('0') << mm << endl;
}
C. Not Equal on a Segment
这题思路很难想,个人想不到pos[]数组要这样做
一开始二分找,超时了
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5, M = 1e6 + 5;
int a[N], n, m;
int pos[N]; //i前面第一个相同的的下标
int main () {
scanf ("%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf ("%d", &a[i]);
if (a[i] == a[i-1]) pos[i] = pos[i-1];
else pos[i] = i;
}
while (m --) {
int l, r, x;
scanf ("%d%d%d", &l, &r, &x);
if (a[r] != x) printf ("%d\n", r);
else {
if (pos[r] <= l) printf ("-1\n");
else printf ("%d\n", pos[r] - 1);
}
}
}
//找到[l,r]区间内不等于x的数的下标
//[1,1e6]
D. Optimal Number Permutation
非常开心!做出了一道1900
构造题,观察式子:
\(i,n\)都是固定的,所以就想一下怎么安排能够使得 \(d_i\) 的值近可能靠近 \(n-i\)。不妨设两个 \(i\) 之间的距离间隔即 \(d_i=n-i\),则可以像下图一样构造:
(最后的 \(n\) 无论如何摆放贡献都是0,所以只需补最后一位的空即可)
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 5, M = N * 2;
int n, a[M];
int main () {
cin >> n;
for (int i = 1, j = 1; i <= n; i += 2, j++) a[j] = a[n-j+1] = i;
for (int i = 2, j = 1; i <= n; i += 2, j++) a[n+j] = a[2*n-j] = i;
a[2 * n] = n;
for (int i = 1; i <= 2 * n; i++) cout << a[i] << ' ';
}
/*
1: 1, n
2: n+1, 2*n-1
3: 2, n-1
4: n+2, 2n-2
...
*/
E. Ants in Leaves
因为蚂蚁是同时向上爬的,所以只需分治处理每颗子树,记录最大时间即可。递归处理每一个叶子的高度,然后排序求解。同一子树内,相同高度的要再等一下(因为不可以同时走到一个点上),可以 \(d[j] = max (d[j-1] + 1, d[j])\)这样更新,记录最大值。
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 5, M = N * 2;
int h[N], e[M], ne[M], idx;
int n, d[N], len, ans;
void add (int a, int b) {
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
void dfs (int u, int fa, int dep) {
bool isleaf = true;
for (int i = h[u]; ~i; i = ne[i]) {
int j = e[i];
if (j == fa) continue;
isleaf = false;
dfs (j, u, dep + 1);
}
if (isleaf) d[len++] = dep;
}
int main () {
memset (h, -1, sizeof h);
cin >> n;
for (int i = 1; i < n; i++) {
int a, b;
cin >> a >> b;
add (a, b), add (b, a);
}
for (int i = h[1]; ~i; i = ne[i]) {
len = 0;
dfs (e[i], 1, 1);
sort (d, d + len);
for (int j = 1; j < len; j++) {
d[j] = max (d[j-1] + 1, d[j]);
}
ans = max (ans, d[len-1]);
}
cout << ans << endl;
}
F. The Sum of the k-th Powers
拉格朗日差值
原理:https://oi-wiki.org/math/poly/lagrange/ (公式推来推去)
题解:https://www.luogu.com.cn/blog/253608/solution-cf622f (和oiwiki上差不多)
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1000005, p = 1000000007;
int n, k, ans, now;
int a[N], f[N], g[N];
int qmi(int a, int k) {
int ans = 1;
while (k) {
if (k & 1) ans = ans * a % p;
k >>= 1;
a = a * a % p;
}
return ans;
}
void solve() {
now = f[0] = g[0] = 1;
for (int i = 1; i <= k + 2; i++) now = now * (n - i) % p, f[i] = f[i - 1] * i % p, g[i] = -g[i - 1] * i % p;
for (int i = 1; i <= k + 2; i++) ans = (ans + a[i] * now % p * qmi(n - i, p - 2) % p * qmi(f[i - 1] * g[k + 2 - i] % p, p - 2)) % p;
}
signed main() {
cin >> n >> k;
for (int i = 1; i <= k + 2 and i <= n; i++) a[i] = (a[i - 1] + qmi(i, k)) % p;
if (n <= k + 2) return cout << a[n], 0;
solve();
cout << (ans + p) % p;
}