Codeforces Round #404 (Div. 2)——ABCDE

题目这里

A.map裸题

#include <bits/stdc++.h>

using namespace std;

map <string, int> p;

string s[] = {
    "Tetrahedron",
    "Cube",
    "Octahedron" ,
    "Dodecahedron",
    "Icosahedron"
};

int ss[] = {4, 6, 8, 12, 20};

int main() {
    ios::sync_with_stdio(false);
    for(int i = 0;i < 5;i ++) p[s[i]] = ss[i];
    int n, m = 0;
    string str;
    cin >> n;
    while(n --) cin >> str, m += p[str];
    cout << m;
    return 0;
}

B.贪心,先上的课尽早下课,后上的课尽量晚点上课

#include <bits/stdc++.h>

using namespace std;

int n, l, r, l1, l2, r1, r2, ans;

int main() {
    ios::sync_with_stdio(false);
    r1 = r2 = 1e9;
    cin >> n;
    while(n --) {
        cin >> l >> r;
        l1 = max(l1, l);
        r1 = min(r1, r);
    }
    cin >> n;
    while(n --) {
        cin >> l >> r;
        l2 = max(l2, l);
        r2 = min(r2, r);
    }
    ans = max(max(0, l2 - r1), max(0, l1 - r2));
    cout << ans;
    return 0;
}

C.先讨论一下

如果n <= m ,那么前 n - 1 天都是当天补满,然后第 n 天被吃光

当 n > m , 前 m 天肯定吃不完的

然后第 m + 1 天鸟走之后(没吃完)下一天再补上,就只有 n - 1 了

第 m + 2 天鸟走之后(没吃完)再补上,就只有 n - 1 - 2 了

......

第 ans 天鸟走之后仓库已经被吃光了

那么就有 n - (ans - m) * (ans - m - 1) / 2 - ans <= 0

令 t = ans - m , 化简以后就有 t * t + t >= 2 * (n - m)

这时候可以选择二分,右边界肯定是sqrt(2 * 1e18)啦,再大会爆long long

当然可以直接开根,然后左右小小调整一下就能出来结果

#include <bits/stdc++.h>

using namespace std;

int main() {
    unsigned long long n, m, ans;
    cin >> n >> m;
    if(n <= m) cout << n;
    else {
        n = (n - m) * 2, ans = sqrt(n);
        while(ans * ans + ans >= n) ans --;ans ++;
        while(ans * ans + ans <  n) ans ++;
        cout << ans + m;
    }
    return 0;
}

D.为了避免重复,我们选择这样一个策略:

每当遇到一个左括号,我们计算包含这个左括号的合法序列数量加入ans

显然如果当前左括号左边有 L 个左括号(不含这个)

右边有 R 个右括号,那么对ans贡献为

sigma(C(L,i ) * C(R,i + 1) ),0 <= i < R

然后我们用一个范德蒙恒等式就变成了求 C(L + R ,R - 1)

剩下求组合数就O(nlogn)预处理,O(1)计算即可

#include <cstdio>
#include <iostream>

const int Mod = 1e9 + 7;

char s[200010];

long long ans, fac[200010], v[200010];

int calc(long long x, int k = Mod - 2) {
    long long ret = 1;
    for(;k;k >>= 1, x = x * x % Mod)
        if(k & 1) ret = ret * x % Mod;
    return ret;
}

long long C(int n, int m) {
    return fac[n] * v[m] % Mod * v[n - m] % Mod;
}

int main() {
    fac[0] = v[0] = 1;
    for(int i = 1;i <= 200000;i ++)
        fac[i] = fac[i - 1] * i % Mod, v[i] = calc(fac[i]);
    int l = 0, r = 0;
    scanf("%s", s);
    for(int i = 0;s[i];i ++) r += (s[i] == ‘)‘);
    for(int i = 0;s[i];i ++) {
        if(s[i] == ‘)‘) r --;
        else ans += C(l + r, r - 1), ans %= Mod, l ++;
    }
    printf("%lld", ans);
    return 0;
}

E.原序列为 1 - n 的排列,每次操作交换两数位置,并操作后求出逆序对个数

转化为二维模型就能很熟悉的联系到cdq上,于是 cdq + 树状数组 解决即可

当然树套树也可做,不再分析思路

用cdq来做呢,我们每次计算这次操作对逆序对数的改变量即为

( l, a[r] )左上和右下矩阵中点的个数 + ( r, a[l] ) 左上和右下矩阵中点的个数

- ( l, a[l] ) 左上和右下矩阵中点的个数 - ( r, a[r] ) 左上和右下矩阵中点的个数

当然我们需要注意避免逆序对的重复计算

另外需要注意我们计算的是改变量,所以答案是需要累加的

#include <bits/stdc++.h>

#define lb(x) (x & (-x))
#define rep(i, j, k) for(int i = j;i <= k;i ++)

using namespace std;

const int maxn = 200010, maxm = maxn * 5;

struct node {
    int x, y, op, bel, id;

    bool operator < (const node &a) const {
        if(x != a.x) return x < a.x;
        if(y != a.y) return y < a.y;
        return id < a.id;
    }
}q[maxm], q0[maxm];

int n, m, k, a[maxn], c[maxn];
long long ans[maxn];

void add(int i, int x) {
    while(i <= n) c[i] += x, i += lb(i);
}

int ask(int i) {
    int ret = 0;
    while(i > 0) ret += c[i], i -= lb(i);
    return ret;
}

void solve(int l, int r) {
    if(l == r) return;
    int mid = (l + r) >> 1, cnt = 0;
    solve(l, mid), solve(mid + 1, r);
    rep(i, l, mid) if(q[i].op == 3 || q[i].op == -3) q0[++ cnt] = q[i];
    rep(i, 1 + mid, r) if(q[i].op != 3 && q[i].op != -3) q0[++ cnt] = q[i];
    sort(q0 + 1, q0 + cnt + 1);
    rep(i, 1, cnt) {
        if(q0[i].op == 3 || q0[i].op == -3) add(q0[i].y, q0[i].op / 3);
        else ans[q0[i].bel] += ask(q0[i].y) * q0[i].op;
    }
    rep(i, 1, cnt) if(q0[i].op == 3 || q0[i].op == -3) add(q0[i].y, q0[i].op / -3);
}

int main() {
    ios::sync_with_stdio(false);
    int l, r;

    cin >> n >> m;
    rep(i, 1, n) a[i] = i, q[++ k] = (node){i, i, 3, 0, k};
    rep(i, 1, m) {
        cin >> l >> r;
        if(l != r) {
            q[++ k] = (node){l - 1, n, -1, i, k};
            q[++ k] = (node){n, a[l] - 1, -1, i, k};
            q[++ k] = (node){l - 1, a[l] - 1, 2, i, k};
            q[++ k] = (node){l, a[l], -3, 0, k};
            q[++ k] = (node){r - 1, n, -1, i, k};
            q[++ k] = (node){n, a[r] - 1, -1, i, k};
            q[++ k] = (node){r - 1, a[r] - 1, 2, i, k};
            q[++ k] = (node){r, a[r], -3, 0, k};
            q[++ k] = (node){l - 1, n, 1, i, k};
            q[++ k] = (node){n, a[r] - 1, 1, i, k};
            q[++ k] = (node){l - 1, a[r] - 1, -2, i, k};
            q[++ k] = (node){l, a[r], 3, 0, k};
            q[++ k] = (node){r - 1, n, 1, i, k};
            q[++ k] = (node){n, a[l] - 1, 1, i, k};
            q[++ k] = (node){r - 1, a[l] - 1, -2, i, k};
            q[++ k] = (node){r, a[l], 3, 0, k};
            swap(a[l], a[r]);
        }
    }
    solve(1, k);
    rep(i, 1, m) {
        ans[i] += ans[i - 1];
        cout << ans[i] << endl;
    }
    return 0;
}

代码写的很丑很暴力,仅供参考

时间: 2024-10-06 05:00:07

Codeforces Round #404 (Div. 2)——ABCDE的相关文章

Codeforces Round #261 (Div. 2)[ABCDE]

Codeforces Round #261 (Div. 2)[ABCDE] ACM 题目地址:Codeforces Round #261 (Div. 2) A - Pashmak and Garden 题意: 一个正方形,它的边平行于坐标轴,给出这个正方形的两个点,求出另外两个点. 分析: 推断下是否平行X轴或平行Y轴,各种if. 代码: /* * Author: illuz <iilluzen[at]gmail.com> * File: A.cpp * Create Date: 2014-0

Codeforces Round #264 (Div. 2)[ABCDE]

Codeforces Round #264 (Div. 2)[ABCDE] ACM 题目地址: Codeforces Round #264 (Div. 2) 这场只出了两题TAT,C由于cin给fst了,D想到正解快敲完了却game over了... 掉rating掉的厉害QvQ... A - Caisa and Sugar[模拟] 题意: Caisa拿s美元去超市买sugar,有n种sugar,每种为xi美元yi美分,超市找钱时不会找美分,而是用sweet代替,当然能用美元找就尽量用美元找.他

Codeforces Round #404 (Div. 2) C 二分,水 D 数学,好题 E 分块

Codeforces Round #404 (Div. 2) C. Anton and Fairy Tale 题意:仓库容量n,每天运来m粮食,第 i 天被吃 i 粮食,问第几天仓库第一次空掉. tags:==SB题 注:二分边界判断,数据范围爆long long判断. // CF404 C #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000&

Codeforces Round #404 (Div. 2) C 二分查找

Codeforces Round #404 (Div. 2) 题意:对于 n and m (1?≤?n,?m?≤?10^18)  找到 1) [n<= m] cout<<n; 2) [n>m]最小的 k => (k -m) * (k-m+1) >= (n-m)*2 成立 思路:二分搜索 #include <bits/stdc++.h> #include <map> using namespace std; #define LL long long

Codeforces Round #260 (Div. 2) ABCDE

A题逗比了,没有看到All ai are distinct. All bi are distinct. 其实很水的.. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 7 #define mnx 100002 8 9 10 struct latop{ 11 int p, q; 12 bo

Codeforces Round #531 (Div. 3) ABCDE题解

Codeforces Round #531 (Div. 3) 题目总链接:https://codeforces.com/contest/1102 A. Integer Sequence Dividing 题意: 给一个数n,然后要求你把1,2.....n分为两个集合,使得两个集合里面元素的和的差的绝对值最小. 题解: 分析可以发现,当n%4==0 或者 n%3==0,答案为0:其余答案为1.之后输出一下就好了. 代码如下: #include <bits/stdc++.h> using name

Codeforces Round #200 (Div. 2) (ABCDE题解)

比赛链接:http://codeforces.com/contest/344 A. Magnets time limit per test:1 second memory limit per test:256 megabytes Mad scientist Mike entertains himself by arranging rows of dominoes. He doesn't need dominoes, though: he uses rectangular magnets inst

Codeforces Round #105 (Div. 2) (ABCDE题解)

比赛链接:http://codeforces.com/contest/148 比较简单的一场,最长的一题也才写了30行多一点 A. Insomnia cure time limit per test:2 seconds memory limit per test:256 megabytes ?One dragon. Two dragon. Three dragon?, - the princess was counting. She had trouble falling asleep, and

Codeforces Round #186 (Div. 2) (ABCDE题解)

比赛链接:http://codeforces.com/contest/313 A. Ilya and Bank Account time limit per test:2 seconds memory limit per test:256 megabytes Ilya is a very clever lion, he lives in an unusual city ZooVille. In this city all the animals have their rights and obl