Codeforces Round #642 (Div. 3)

A

#include <bits/stdc++.h>
#define all(n) (n).begin(), (n).end()
#define se second
#define fi first
#define pb push_back
#define mp make_pair
#define sqr(n) (n)*(n)
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef vector<int> VI;
typedef double db;
 
const int maxn = 1e5 + 5;
 
int n, m, _;
int a[maxn];
 
int main()
{
    ios::sync_with_stdio(0); cin.tie(0);
    for (cin >> _; _; --_)
    {
        cin >> n >> m;
        if (n == 1) cout << 0 << '\n';
        else if (n == 2) cout << m << '\n';
        else cout << (m << 1) << '\n';
    }
    return 0;
}

B

贪心

#include <bits/stdc++.h>
#define all(n) (n).begin(), (n).end()
#define se second
#define fi first
#define pb push_back
#define mp make_pair
#define sqr(n) (n)*(n)
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef vector<int> VI;
typedef double db;
 
const int maxn = 1e5 + 5;
 
int n, m, _;
int a[maxn], b[maxn];
 
int main()
{
    ios::sync_with_stdio(0); cin.tie(0);
    for (cin >> _; _; --_)
    {
        cin >> n >> m; a[0] = 0;
        rep (i, 1, n) cin >> a[i], a[0] += a[i];
        rep (i, 1, n) cin >> b[i];
 
        sort(a + 1, a + 1 + n);
        sort(b + 1, b + 1 + n);
 
        rep (i, 1, m) 
            if (b[n + 1 - i] - a[i] > 0) a[0] += b[n + 1 - i] - a[i];
            else break;
 
        cout << a[0] << '\n';
    }
    return 0;
}

C

可以推公式 O(1), 但没必要直接O(n)

#include <bits/stdc++.h>
#define all(n) (n).begin(), (n).end()
#define se second
#define fi first
#define pb push_back
#define mp make_pair
#define sqr(n) (n)*(n)
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef vector<int> VI;
typedef double db;
 
const int maxn = 2e5 + 5;
 
int n, m, _;
int a[maxn];
 
priority_queue<pair<int, PII>> q;
 
int main()
{
    ios::sync_with_stdio(0); cin.tie(0);
    for (cin >> _; _; --_)
    {
        cin >> n; 
        int a = n >> 1;
        //cout << a << '\n';
        ll sum = (ll)(1 + a) * a / 2;
        rep (i, 1, a) sum += (ll)i * (i * 2 - 1);
        cout << (sum << 2) << '\n';
    }
    return 0;
}

D

优先队列

#include <bits/stdc++.h>
#define all(n) (n).begin(), (n).end()
#define se second
#define fi first
#define pb push_back
#define mp make_pair
#define sqr(n) (n)*(n)
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef vector<int> VI;
typedef double db;
 
const int maxn = 2e5 + 5;
 
int n, m, _;
int a[maxn];
 
priority_queue<pair<int, PII>> q;
 
int main()
{
    ios::sync_with_stdio(0); cin.tie(0);
    for (cin >> _; _; --_)
    {
        cin >> n; m = 0;
        q.push({ n, { -1, n}});
        while (m <= n && !q.empty())
        {
            int s = q.top().fi;
            PII p = q.top().se; q.pop();
            int mid = (-p.fi + p.se) >> 1;
            a[mid] = ++m;
            if (s == 1) continue;
            if (mid != -p.fi) q.push({ mid + p.fi, {p.fi, mid - 1}});
            q.push({ p.se - mid, { - mid - 1, p.se}});
        }
        rep (i, 1, n) cout << a[i] << ' ';
        cout << '\n';
    }
    return 0;
}

E

吐了,卡了半天,结果是sum开小了,要两倍空间

划分子集,即 % k 余数相同

用dp

再第i个灯阶段
属于 c = i % k 子集, 选择 c 子集作为答案

  f[c][0] 表示到i阶段, c子集所有灯关闭的最小步骤

  f[c][1] 表示i阶段, 子集c中从某个 (d + b * k) 灯开始到 i灯全部打开的最小步骤

  f[c][2] 表示i阶段, 子集c中从某个 (d + b * k) 灯 到 (x + y * k) 灯亮着, 让后到 i灯都灭着, 的最小步骤

转移方程

if (i - k < 0) d = sum[0];
else d = sum[i - k];

f[c][2] = min(f[c][2], f[c][1]) + sum[i] - d;
if (f[c][0] <= f[c][1]) f[c][1] = f[c][0] + sum[i - 1] - d;
else f[c][1] = f[c][1] + sum[i - 1] - d;
f[c][0] = sum[i];

if (s[i] == '0') ++f[c][1];

记得还要走完真个过程k, 所以走完n之后, 还要再走 rep(i, n + 1, n + k)

这就是为什么要sum要开两倍(其实不开也行)

#include <bits/stdc++.h>
#define all(n) (n).begin(), (n).end()
#define se second
#define fi first
#define pb push_back
#define mp make_pair
#define sqr(n) (n)*(n)
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef vector<int> VI;
typedef double db;

const int maxn = 1e6 + 5;

int n, m, _, k;
int a[maxn], sum[maxn << 1], f[maxn][3];
char s[maxn];

int main()
{
    ios::sync_with_stdio(0); cin.tie(0);
    for (cin >> _; _; --_)
    {
        cin >> n >> k >> s + 1;
        rep(i, 0, k - 1) f[i][0] = 0, f[i][1] = f[i][2] = 1e9;

        rep(i, 1, n)
        {
            sum[i] = sum[i - 1] + (s[i] == '1');
            int c = i % k, d;

            if (i - k < 0) d = sum[0];
            else d = sum[i - k];

            f[c][2] = min(f[c][2], f[c][1]) + sum[i] - d;
            if (f[c][0] <= f[c][1]) f[c][1] = f[c][0] + sum[i - 1] - d;
            else f[c][1] = f[c][1] + sum[i - 1] - d;
            f[c][0] = sum[i];

            if (s[i] == '0') ++f[c][1];
        }

        rep(i, n + 1, n + k)
        {
            sum[i] = sum[i - 1];
            int c = i % k;

            f[c][2] = min(f[c][2], f[c][1]) + sum[i] - sum[i - k];
            if (f[c][0] <= f[c][1]) f[c][1] = f[c][0] + sum[i - 1] - sum[i - k];
            else f[c][1] = f[c][1] + sum[i - 1] - sum[i - k];
            f[c][0] = sum[i];
        }

        int ans = 2e9;
        rep(i, 0, k - 1) ans = min(ans, min(f[i][0], min(f[i][1], f[i][2])));
        cout << ans << '\n';
    }
    return 0;
}
posted @ 2020-05-15 11:23  洛绫璃  阅读(263)  评论(0编辑  收藏  举报