Codeforces Round #624 (Div. 3)

Codeforces Round #624 (Div. 3)

昨天vp的
https://codeforces.com/contest/1311

A. Add Odd or Subtract Even

以为成另一道题了。。。这里每次加减的数是可变的,所以:

#include <bits/stdc++.h>

using namespace std;

void solve () {
    int a, b, ans;
    cin >> a >> b;
    if (a == b) ans = 0;
    else if (a < b) {
        int d = b -  a;
        if (d & 1)  ans = 1;
        else    ans = 2;
    }
    else {
        int d = a - b;
        if (d & 1)  ans = 2;
        else    ans = 1;
    }
    cout << ans << endl;
}

int main () {
    int t;
    cin >> t;
    while (t --) {
        solve ();
    }
}
//每次增减的数可变

B. WeirdSort

模拟完全冒泡排序,判断下标是否可以交换
优化:连续段一起交换
优化Code

#include <bits/stdc++.h>

using namespace std;
const int N = 105;
int a[N], n, m, x;

void solve () {
    cin >> n >> m;
    set <int> s;
    for (int i = 0; i < n; i ++)   cin >> a[i];
    for (int i = 0; i < m; i ++)   cin >> x, s.insert (x);
    
    for (int i = 1, j = 0; i <= n; i ++) { 
        if (s.count (i))    continue;
        sort (a + j, a + i);
        j = i;
    }
    if (is_sorted (a, a + n))   cout << "YES\n";
    else    cout << "NO\n";
}

int main () {
    int t;
    cin >> t;
    while (t --) {
        solve ();
    }
}

//冒泡
//当一段连续的pi存在时,就可以直接对这一段a[pi+i~pi+j]进行排序
//区间排序

C. Perform the Combo

有过少个比它大与等于的对应位置就加几
这里使用的是二分查找

#include <bits/stdc++.h>

using namespace std;
const int N = 2e5 + 5;
int n, m, ans[27];

void solve () {
    string s;
    cin >> n >> m >> s;
    vector <int> v;
    //vector <int> cnt(n+1, 0);
    for (int i = 0; i < m; i ++) {
        int x;
        cin >> x;
        v.push_back (x);
    }
    v.push_back (n);
    sort (v.begin (), v.end());

    memset (ans, 0, sizeof ans);
    //有过少个比它大与等于的就加几
    for (int i = 0; i < n; i ++) {
        int x = lower_bound (v.begin(), v.end(), i+1) - v.begin();
        x = m - x + 1;
        ans[s[i] - 'a'] += x;
    }

    for (int i = 0; i < 26; i ++)   cout << ans[i] << ' ';
    cout << endl;
}

int main () {
    int t;
    cin >> t;
    while (t --) {
        solve ();
    }
}

//前缀和差分
//区间加

D. Three Integers

a的变化范围只能在[1,2a](超过2a不如变成1)
从而b在[a, 2b],
从而确定c的范围[b(c/b), b(c/b) + b]

#include <bits/stdc++.h>
#define int long long

using namespace std;
const int inf = 0x7ffffffffffffff;

void solve () {
    int a, b, c;
    cin >> a >> b >> c;
    int ans = inf, A, B, C;
    for (int i = 1; i <= 2 * a; i ++)
        for (int j = i; j <= 2 * b; j += i)
            for (int k = 0; k <= 1; k ++) {
                int l = j * (c / j) + k * j; //取整
                int t = abs (i - a) + abs(j - b) + abs (c - l);
                if (t < ans) {
                    ans = t, A = i, B = j, C = l;
                }
            }
    
    cout << ans << endl << A << ' ' << B << ' ' << C << endl;
}

signed main () {
    int t;
    cin >> t;
    while (t --) {
        solve ();
    }
}

//每次可以+1或-1,使得 b%a==0 && c%b == 0
//a的变化范围只能在[1,2a]

E. Construct the Binary Tree

先放上分析,明天来补code

//n个节点的二叉树,深度之和为d
//根节点算第1层,num[1]=1
//深度计算:num[i]*(i-1),i表示层数且(0<=num[i]<=num[i-1]*2)
//层数d: [log2n+1, n]

//num[1]+2*num[2]+3*num[3]+...+(n-1)*num[n-1]=d
//

F. Moving Points

分析:
对于任意xj < xi(坐标):
若 vj > vi,则一定会追上,即dis(i,j)=0;
若 vj <= vi,则追不上,即dis(i,j)=xi-xj;
BIT 求和

#include <bits/stdc++.h>
#define int long long

using namespace std;
typedef pair<int, int> pii;
const int N = 2e5 + 5;
int n;
vector <int> a; //点的速度
int v[N], x[N]; //vj<=vi的j的个数   \sum_xj
pii p[N]; //坐标 速度

int lowbit (int x) {
    return x & (-x);
}

void add (int *b, int x, int v) {
    for (int i = x; i <= n; i += lowbit (i))
        b[i] += v;
}

int query (int *b, int x) {
    int ans = 0;
    for (int i = x; i; i -= lowbit (i))
        ans += b[i];
    return ans;
}

signed main () {
    cin >> n;
    for (int i = 0; i < n; i ++)    cin >> p[i].first;
    for (int i = 0; i < n; i ++)    cin >> p[i].second, a.push_back (p[i].second);

    sort (p, p + n);
    sort (a.begin(), a.end());
    a.erase ((a.begin(), a.end()), a.end());
    
    int ans = 0;
    for (int i = 0; i < n; i ++) {
        int pos = upper_bound (a.begin(), a.end(), p[i].second) - a.begin(); //找到第一个>的
        ans += query(v, pos) * p[i].first - query (x, pos);
        add (v, pos, 1), add (x, pos, p[i].first);
    }
    cout << ans << endl;
}
posted @ 2022-07-14 23:53  Sakana~  阅读(24)  评论(0编辑  收藏  举报