Codeforces #370(div2)题解

    xiaoxiao2022-06-27  37

    A. Memory and Crow

    列个公式推一下就可以了

    #include <iostream> #include <cstring> #include <stack> #include <vector> #include <set> #include <map> #include <cmath> #include <queue> #include <sstream> #include <iomanip> #include <fstream> #include <cstdio> #include <cstdlib> #include <climits> #include <deque> #include <bitset> #include <algorithm> using namespace std; #define PI acos(-1.0) #define LL long long #define PII pair<int, int> #define PLL pair<LL, LL> #define mp make_pair #define IN freopen("in.txt", "r", stdin) #define OUT freopen("out.txt", "wb", stdout) #define scan(x) scanf("%d", &x) #define scan2(x, y) scanf("%d%d", &x, &y) #define scan3(x, y, z) scanf("%d%d%d", &x, &y, &z) #define sqr(x) (x) * (x) const int maxn = 100000 + 5; int a[maxn], b[maxn]; int main() { int n; scan(n); for (int i = 1; i <= n; i++) scan(a[i]); for (int i = 1; i <= n - 1; i++) b[i] = a[i] + a[i + 1]; for (int i = 1; i <= n - 1; i++) printf("%d ", b[i]); printf("%d\n", a[n]); return 0; }

    B. Memory and Trident

    如果总次数是奇数一定无解。偶数的话分别统计一下UDLR出现的次数,然后相反两个方向的相互转换一定更优。最后单出来的再转换一次

    #include <iostream> #include <cstring> #include <stack> #include <vector> #include <set> #include <map> #include <cmath> #include <queue> #include <sstream> #include <iomanip> #include <fstream> #include <cstdio> #include <cstdlib> #include <climits> #include <deque> #include <bitset> #include <algorithm> using namespace std; #define PI acos(-1.0) #define LL long long #define PII pair<int, int> #define PLL pair<LL, LL> #define mp make_pair #define IN freopen("in.txt", "r", stdin) #define OUT freopen("out.txt", "wb", stdout) #define scan(x) scanf("%d", &x) #define scan2(x, y) scanf("%d%d", &x, &y) #define scan3(x, y, z) scanf("%d%d%d", &x, &y, &z) const int maxn = 100000 + 5; char s[maxn]; int main() { scanf("%s", s); int n = strlen(s); if (n & 1) { puts("-1"); return 0; } int u = 0, d = 0, r = 0, l = 0; for (int i = 0; i < n; i++) { if (s[i] == 'U') u++; if (s[i] == 'D') d++; if (s[i] == 'R') r++; if (s[i] == 'L') l++; } int t1 = abs(u - d) / 2; int t2 = abs(r - l) / 2; int ans = t1 + t2; if (abs(u - d) % 2 == 1) ans++; printf("%d\n", ans); return 0; }

    C. Memory and De-Evolution

    C题想清楚了超级简单,首先条件就是满足三角形定则 最先考虑的是从x向y转换,每次贪心的去选择(尽可能靠近y),但是第三个样例发现显然不成立 但是如果从y出发, 去倒推x的话发现贪心是成立的

    #include <iostream> #include <cstring> #include <stack> #include <vector> #include <set> #include <map> #include <cmath> #include <queue> #include <sstream> #include <iomanip> #include <fstream> #include <cstdio> #include <cstdlib> #include <climits> #include <deque> #include <bitset> #include <algorithm> using namespace std; #define PI acos(-1.0) #define LL long long #define PII pair<int, int> #define PLL pair<LL, LL> #define mp make_pair #define IN freopen("in.txt", "r", stdin) #define OUT freopen("out.txt", "wb", stdout) #define scan(x) scanf("%d", &x) #define scan2(x, y) scanf("%d%d", &x, &y) #define scan3(x, y, z) scanf("%d%d%d", &x, &y, &z) #define sqr(x) (x) * (x) int main() { int x, y, tot = 0; scan2(x, y); int a = y, b = y, c = y; while (a < x) { c = b; b = a; a = b + c - 1; tot++; } printf("%d\n", tot + 2); return 0; }

    D. Memory and Scores

    状态表示:d[i][j] 经过i轮,a和b分数相差j(未计入初始值) 转移方程:d[i][j] = d[i - 1][j - 2k] + d[i - 1][j - (2k - 1)] * 2 + … + d[i - 1][j] * (2k + 1) + d[i - 1][j + 1] * 2k + d[i - 1][j + 2] * (2k - 1) + … + d[i - 1][j + 2k] 时间复杂度O(n^2 * k * t),显然会T 发现右边依次按照1,2,3,4的速度在增长,再考虑d[i][j - 1],发现两个做差后右边变成了前缀和

    d[i][j] = d[i - 1][j - 1] + sum[j + 2k] - sum[j - 1] - (sum[j - 1] - sum[j - 1 - (2k + 1)])

    将转移的时间复杂度降为了O(1)

    #include <iostream> #include <cstring> #include <stack> #include <vector> #include <set> #include <map> #include <cmath> #include <queue> #include <sstream> #include <iomanip> #include <fstream> #include <cstdio> #include <cstdlib> #include <climits> #include <deque> #include <bitset> #include <algorithm> using namespace std; #define PI acos(-1.0) #define LL long long #define PII pair<int, int> #define PLL pair<LL, LL> #define mp make_pair #define IN freopen("in.txt", "r", stdin) #define OUT freopen("out.txt", "wb", stdout) #define scan(x) scanf("%d", &x) #define scan2(x, y) scanf("%d%d", &x, &y) #define scan3(x, y, z) scanf("%d%d%d", &x, &y, &z) #define sqr(x) (x) * (x) const int maxn = 200000 + 200; const int oft = 200000 + 200; const int mod = 1000000007; LL d[2][maxn * 2], sum[maxn * 2]; int a, b, k, t; int main() { scanf("%d%d%d%d", &a, &b, &k, &t); d[0][0 + oft] = 1; int bd = 2 * k * t, o = 0; for (int i = 1; i <= t; i++, o ^= 1) { for (int j = -bd; j <= bd; j++) { sum[j + oft] = sum[j - 1 + oft] + d[o][j + oft]; sum[j + oft] %= mod; } int tbd = 2 * k * i; d[o ^ 1][-tbd + oft] = 1; for (int j = -tbd + 1; j <= tbd; j++) { d[o ^ 1][j + oft] = d[o ^ 1][j - 1 + oft] + (sum[min(j + 2 * k, bd) + oft] - sum[j - 1 + oft]) - (sum[j - 1 + oft] - sum[max(j - 1 - (2 * k + 1), -bd) + oft]); d[o ^ 1][j + oft] += mod; d[o ^ 1][j + oft] %= mod; } } LL ans = 0; for (int i = b - a + 1; i <= bd; i++) { ans += d[o][i + oft]; ans %= mod; } printf("%d\n", ans); return 0; }

    E.Memory and Casinos

    终于补完了div2一套题了= =看了题解才会 把公式推出来后发现就是线段树的单点修改,区间查询 cf上的题解:

    #include <iostream> #include <cstring> #include <stack> #include <vector> #include <set> #include <map> #include <queue> #include <sstream> #include <iomanip> #include <fstream> #include <cstdio> #include <cstdlib> #include <climits> #include <deque> #include <bitset> #include <algorithm> using namespace std; #define PI acos(-1.0) #define LL long long #define PII pair<int, int> #define PLL pair<LL, LL> #define mp make_pair #define IN freopen("in.txt", "r", stdin) #define OUT freopen("out.txt", "wb", stdout) #define scan(x) scanf("%d", &x) #define scan2(x, y) scanf("%d%d", &x, &y) #define scan3(x, y, z) scanf("%d%d%d", &x, &y, &z) #define sqr(x) (x) * (x) const int maxn = 100000 << 2; double A[maxn], B[maxn]; double pr, ur, a, b; int n, Q; int y1, y2, p, y3, y4; double v; void pushup(int o) { A[o] = A[o << 1] * A[o << 1 | 1]; B[o] = B[o << 1] + B[o << 1 | 1] * A[o << 1]; } void build(int o, int L, int R) { if (L == R) { scanf("%lf%lf", &a, &b); double pr = a / b; A[o] = (1 - pr) / pr; B[o] = A[o]; return; } int M = L + (R - L) / 2; build(o << 1, L, M); build(o << 1 | 1, M + 1, R); pushup(o); } void update(int o, int L, int R) { if (L == R) { A[o] = v; B[o] = v; return; } int M = L + (R - L) / 2; if (p <= M) update(o << 1, L, M); else update(o << 1 | 1, M + 1, R); pushup(o); } pair<double, double> query(int o, int L, int R) { if (y1 <= L && y2 >= R) return mp(A[o], B[o]); int M = L + (R - L) / 2; double tb = 0, ta = 1.0; if (y1 <= M) { pair<double, double> tmp = query(o << 1, L, M); ta *= tmp.first; tb += tmp.second; } if (y2 > M) { pair<double, double> tmp = query(o << 1 | 1, M + 1, R); tb += (tmp.second * ta); ta *= tmp.first; } return mp(ta,tb); } int main() { scan2(n, Q); build(1, 1, n); while (Q--) { int op; double t1, t2; scan(op); if (op == 1) { scanf("%d%lf%lf", &p, &t1, &t2); double tv = t1 / t2; v = (1 - tv) / tv; update(1, 1, n); } else { scan2(y1, y2); printf("%.12lf\n", 1.0/ (1 + query(1, 1, n).second)); } } return 0; }
    转载请注明原文地址: https://ju.6miu.com/read-1124033.html

    最新回复(0)