2022 China Collegiate Programming Contest (CCPC) Guilin Site

A.Lily

Problem - A - Codeforces

题意

思路

数所有周围没L的格子

#include <bits/stdc++.h>

using i64 = long long;

constexpr int N = 2e5 + 10;
constexpr int mod = 1e9 + 7;
constexpr int Inf = 0x3f3f3f3f;
constexpr double eps = 1e-10;

std::string s;

int n;

void solve() {
    std::cin >> n >> s;
    s = " " + s;
    for (int i = 1; i <= n; i ++) {
        if (s[i] == 'L') continue;
        if (i == 1) {
            if (s[i + 1] != 'L') {
                s[i] = 'C';
            }
        }else if (i == n) {
            if (s[i - 1] != 'L') {
                s[i] = 'C';
            }
        }else {
            if (s[i - 1] != 'L' && s[i + 1] != 'L') {
                s[i] = 'C';
            }
        }
    }
    std::cout << s.substr(1, n) << "\n";
}
signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int t = 1;
    while(t --) {
        solve();
    }
    return 0;
}

M. Youth Finale

Problem - M - Codeforces

题意

给定一个排列,每次可以翻转这个排列,或者循环往左一个单位,给定操作序列,问操作之后给序列做冒泡排序的操作次数

思路

冒泡排序的操作次数其实就是逆序对的对数,那就是求操作之后的逆序对有多少

考虑DS的思想,我们对它的逆序对统计,考虑两次操作对逆序对的贡献

第一种就是逆序对个数 = 长度 - 逆序对个数

对于第二种,考虑操作一下,变化量就是 cur - pre

cur就是原序列中比操作数大的数

pre就是原序列中比操作数小的数

减一下就行

然后发现需要维护操作数,那就拿个 idx 维护即可,发现第一种操作会让方向反向,因此维护 x 方向

#include <bits/stdc++.h>

#define int long long

using i64 = long long;

#define lowbit(x) (x & (- x))

constexpr int N = 1e6 + 10;
constexpr int mod = 1e9 + 7;
constexpr int Inf = 0x3f3f3f3f;
constexpr double eps = 1e-10;

std::string s;

int n, m;
int p[N];
int tr[N];

void add(int x, int k) {
    for (int i = x; i <= n; i += lowbit(i)) tr[i] += k;
}
int query(int x) {
    int res = 0;
    for (int i = x; i; i -= lowbit(i)) res += tr[i];
    return res;
}
void solve() {
    std::cin >> n >> m;
    for (int i = 1; i <= n; i ++) std::cin >> p[i];
    std::cin >> s;
    s = " " + s;

    int cur = 0;
    for (int i = 1; i <= n; i ++) {
        cur += query(n) - query(p[i]);
        add(p[i], 1);
    }
    std::cout << cur << "\n";

    int idx = 1, x = 1;
    for (int i = 1; i <= m; i ++) {
        if (s[i] == 'S') {
            cur = cur - (p[idx] - 1) + (n - (p[idx] + 1) + 1);
            idx = idx + x;
            if (idx == n + 1) idx = 1;
            else if (idx == 0) idx = n;
        }else {
            cur = n * (n - 1) / 2 - cur;
            idx = idx - x;
            if (idx == 0) idx = n;
            else if (idx == n + 1) idx = 1;
            x = -x;
        }
        std::cout << cur % 10;
    }
    std::cout << "\n";
}
signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int t = 1;
    while(t --) {
        solve();
    }
    return 0;
}

E. Draw a triangle

题意

思路

#include <bits/stdc++.h>

#define int long long

using i64 = long long;

#define lowbit(x) (x & (- x))

constexpr int N = 1e6 + 10;
constexpr int mod = 1e9 + 7;
constexpr int Inf = 0x3f3f3f3f;
constexpr double eps = 1e-10;

int a, b, c, d;
int v, u;

int exgcd(int a, int b, int &v, int &u) {
    if (!b) {
        v = 1, u = 0;
        return a;
    }
    int gcd = exgcd(b, a % b, u, v);
    u -= (a / b) * v;
    return gcd;
}
void solve() {
    std::cin >> a >> b >> c >> d;
    int x = c - a;
    int y = d - b;
    int gcd = exgcd(x, -y, v, u);
    std::cout << a + u << " " << b + v << "\n";
}
signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int t = 1;
    std::cin >> t;
    while(t --) {
        solve();
    }
    return 0;
}

C. Array Concatenation

题意

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
#define int long long
typedef long long lld;
const int N = 100005;
const lld p = 1000000007;
lld sum[N], a[N], tot[N];
lld powe(lld a, lld b) {
	lld base = 1; 
	while(b) {
		if(b & 1) base = base * a % p;
		a = a * a % p; b >>= 1;
	}
	return base;
}
lld pos_t = 0, neg_t = 0, squ = 0;
lld ans1 = 0, ans2 = 0;
signed main() {
	int n, m; scanf("%lld%lld", &n, &m);
	for(int i = 1; i <= n; i++) {
		scanf("%lld", &a[i]);
		squ += a[i]; squ %= p;
	}
	for(int i = 1; i <= n; i++) {
		sum[i] = (sum[i - 1] + a[i]) % p;
		pos_t = (pos_t + sum[i]) % p;
	}
	for(int i = n; i >= 1; i--) {
		tot[i] = (tot[i + 1] + a[i]) % p;
		neg_t = (neg_t + tot[i]) % p;
	}
	squ = squ * n % p;
	ans1 = ans2 = squ * powe(2, m - 1) % p * (powe(2, m) - 1 + p) % p; 
	ans1 = (ans1 + powe(2, m - 1) * pos_t % p) % p;
	ans1 = (ans1 + powe(2, m - 1) * neg_t % p) % p;
	ans2 = (ans2 + powe(2, m) * pos_t % p) % p;
	printf("%lld", max(ans1, ans2)); 
	return 0;
} 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值