Codeforces #370(div2)题解

25 篇文章 0 订阅
14 篇文章 0 订阅
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上的题解:
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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值