Codeforces round 919 (div2)

Problem - A - Codeforces

暴力枚举 就可以;

c++ 复制代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
vector<int>a;
int n;
signed main()
{
    int _;
    cin >> _;
    while(_ --)
    {
        a.clear();
        cin >> n;
        int p = 1 , q = 1e9;
        
        while(n --)
        {
            int x , k;
            cin >> x >> k;
            
            if(x == 1) p = max(p , k);
            else if(x == 2) q = min(q , k);
            else a.push_back(k);
        }
        int num = 0;
        for(int i = 0 ; i < a.size() ; i ++)
            if(a[i] <= q && a[i] >= p) num ++;
        if(q < p) cout << 0 << endl;
        else cout << q - p + 1 - num << endl;

    }
    
    return 0;
}

Problem - B - Codeforces

对于这道题,因为鲍勃需要将数组总和变得最小,所以他一定会用尽每次数次将最大的数几个数乘上-1,而爱丽丝需要将数组的总和变得最大,所以他可以进行删除操作,来防止 鲍勃将大数乘上-1从而使数组总和变小,所以我们可以使用前缀的方法,来进行判断;

c++ 复制代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
#define int long long
int a[N];
int p[N];

void solve()
{
    int n , k , x;
    cin >> n >> k >> x;

    for(int i = 1 ; i <= n ; i ++)  cin >> a[i];
    
    sort(a + 1 , a + 1 + n); //进行排序;
    
    for(int i = 1; i <= n ; i ++) p[i] = p[i - 1] + a[i];
    
    int res = -2e9;
    
    for(int i = 0 ; i <= k ; i ++) //枚举所删的个数
    {
        res = max(res , p[max(n - i - x ,(LL)0)] - (p[n - i] - p[max(n - x - i, (LL)0)]));
    }
    cout << res << endl;
}

signed main()
{
    int _;
    cin >> _;
    
    while(_ --)
    {
        solve();
    }
    
    return 0;
}

Problem - C - Codeforces

​ 这一题,用到数学的知识,我们发现 每一段 必须均匀分割,那么也就是说 这个分割的长度k必须是数组长度n的因数;这是第一;然后我们需要 让每一段的数 对k取模之后 与 后一段 的同一位置的数 对k取模之后的余数 要想等,也就是说

\[\{x_1+...+x_{k}\} \ + \ \{x_{k + 1}+...+x_{2k}\}\ + \ \{x_{n-k + 1} + ...+x_{n}\} \]

按照上面所说就是要保证

\[x_1\ \equiv\ x_{k+1}\ (mod\ k) \]

\[x_2\ \equiv\ x_{k+2}\ (mod\ k) \]

\[x_k\ \equiv\ x_{2k}\ (mod\ k) \]

这只是拿两段来举例,对于每一段来说 都是这样,让每一段相同位置的数取模k余数相同

根据这个同余公式移向,我们可以得出:$ |x-x_{k+1}|\equiv 0 \ (mod\ k) $

如果k是|x_1-x_{k+1}|的因数, 那么x和x_{k+1}一定同余k\

所以当k为|x_1-x_{k+1}|的因数时,可以满足这个式子,若k又是|x_2-x_{k+2}|的因数,就满足上面 两个式子\

所以如果 k是 \(|x_1−x_{1+k}| , |x_2−x_{2+k}| ,..., |x_{n-k}−x_{n}|\)的因数,则满足所有条件:

所以k就为\(gcd(x_1−x_{1+k} , |x_2−x_{2+k}| ,..., |x_{n-k}−x_{n}|)\)

c++ 复制代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
#define int long long
int a[N];
int n;

void init()
{
    for(int i = 1 ; i <= n ; i ++) a[i] = 0;
}

void solve()
{
    
    int n;
    cin >> n;
    
    init();
    
    int ans = 0;
    
    for(int i = 1 ; i <= n ; i ++) cin >> a[i];
    
    for(int k = 1 ; k <= n ; k ++) //枚举因数
    {
        if(n % k != 0) continue;
        else //如果可以被n整除
        {
            int res = 0;
            for(int i = 1 ; i + k <= n ; i ++)//从x1开始枚举一直枚举到第x_n-k
            {
                res = __gcd(res , abs(a[i + k] - a[i])); //公约数;
            }

            if(res != 1) ans ++;//找到公约数,如果不是1的话就会得分
        }
    }
    
    cout << ans << endl;
}

signed main()
{
    int _;
    cin >> _;
    
    while(_ --)
    {
        solve();
    }
    
    return 0;
}