Contestant. Rank 1948. Rating +8.
A. Serval and Mocha’s Array
题意
给定一个数组 
思路
首先,最优的方法当然是互质,只要把互质的两个数放到第一个,那么后面的 
其次,前两个数可以有公约数 
所以,我们只需找出一对数,满足 
时间复杂度:
对应AC代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>
const int N = 2e5 + 10, inf = 0x3f3f3f3f;
int a[N];
int gcd(int x, int y) {
    while (y != 0) {
        int tmp = x;
        x = y;
        y = tmp % y;
    }
    return x;
}
signed main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int t;
    cin >> t;
    while(t --){
        int n;
        cin >> n;
        for(int i=0;i<n;i++) cin >> a[i];
        bool f = false;
        for(int i=0;i<n;i++)
            for(int j=i;j<n;j++){
                if(gcd(a[i], a[j]) <= 2) {
                    f = true;
                    break;
                }
            }
        cout << (f ? "YES\n" : "NO\n");
    }
} 为什么赛后反而思路这么清晰了((
B. Serval and Inversion Magic
题意
给定一个二进制字符串,任选一个区间,将区间内的所有数取反,输出是否可以将整个字符串变为回文字符串。
思路
考虑到回文串的对称性,我们只需修改 
下面是一种模拟思路:
我们不妨从外向里遍历,比较 
否则,一定是有解的。
时间复杂度:
对应AC代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>
const int N = 2e5 + 10, inf = 0x3f3f3f3f;
signed main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int t;
    cin >> t;
    while(t --){
        int n;
        cin >> n;
        string a;
        cin >> a;
        bool f = true, have = false, now = false;
        for(int i=0;i<n/2;i++){
            if(a[i] == a[n - i - 1]){
                if(now){
                    now = false;
                    have = true;
                }
            }else{
                if(have){
                    f = false;
                    break;
                }
                now = true;
            }
        }
        cout << (f ? "YES\n" : "NO\n");
    }
} 我的评价是:比A题简单
C. Serval and Toxel’s Arrays
题意
给定一个无重复元素的数组 
思路
显然,我们不可能去暴力计算,而相反地,我们可以将问题拆分为所有单个数字的贡献和。
具体地说,对于一个数字,若它自始至终未被修改,那么任意两个数组组合,都会留下它,那么它的贡献即为 
若它被修改了,那么在它未出现的时候,它将毫无贡献。因此,我们需要减去这些无贡献的数组组合,也就是 $C{m - cnt + 1}^2
当然,我们还需算出一个数的出现次数 
时间复杂度:
对应AC代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>
const int N = 4e5 + 10, inf = 0x3f3f3f3f;
int cnt[N];
pii a[N];
signed main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int t;
    cin >> t;
    while(t --){
        int n, m;
        cin >> n >> m;
        for(int i=1;i<=n+m;i++) cnt[i] = 0;
        for(int i=1;i<=n;i++) {
            cin >> a[i].first;
            a[i].second = 0;
        }
        for(int i=1;i<=m;i++){
            int p, v;
            cin >> p >> v;
            cnt[a[p].first] += i - a[p].second;
            a[p] = {v, i};
        }
        for(int i=1;i<=n;i++) cnt[a[i].first] += m + 1 - a[i].second;
        int ans = 0;
        for(int i=1;i<=n+m;i++){
            if(cnt[i] == 0) continue;
            if(cnt[i] > m) ans += m * (m + 1) / 2;
            else ans += (m * (m + 1) - (m - cnt[i]) * (m - cnt[i] + 1)) / 2;
        }
        cout << ans << '\n';
    }
} 我蠢了
- 本文链接 https://floating-ocean.github.io/blog_old/posts/2909166420/
 - 版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!