Grakn Forces 2020

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)
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef vector<int> VI;
typedef double db;
 
template<class T1, class T2> bool umin(T1& a, T2 b) { return a > b ? (a = b, true) : false; }
template<class T1, class T2> bool umax(T1& a, T2 b) { return a < b ? (a = b, true) : false; }
template<class T> void clear(T& a) { T().swap(a); }
 
const int N = 1e5 + 5;
 
int n, m, _, k;
int a[N], b[N], c[N], d[N];
 
int main() {
    IOS;
    for (cin >> _; _; --_) {
        cin >> n;
        rep (i, 1, n) cin >> a[i], d[i] = 0;
        rep (i, 1, n) cin >> b[i];
        rep (i, 1, n) cin >> c[i];
        rep (i, 1, n) {
            if (a[i] != d[i - 1] && d[i + 1] != a[i]) d[i + n] = d[i] = a[i];
            else if (b[i] != d[i - 1] && d[i + 1] != b[i]) d[i + n] = d[i] = b[i];
            else d[i + n] = d[i] = c[i]; 
        }
 
        rep (i, 1, n) cout << d[i] << ' ';
        cout << '
';
    }
    return 0;
}

B

贪心, 先不考虑 k, 则 a 数组完全等于 b_1

在考虑 k, a 数组有 m 个不相等的数, 则 b_1中有 m 个不相等的数

m <= k 直接出答案

m >= k, 那就使得, b_1 中 第 k 个数不同后, 都为 k

那么就使得 k - m 个数还未凑够

那就接着 b_2呗, 不过 你只能用 k - 1 个数了, 因为你的 b_1 前 m 个不同的数完全等于 a, 你的 b_2 这些位置必须为 0

你要用一个 0 来不干扰前面选好的, 所以是 k- 1

#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)
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef vector<int> VI;
typedef double db;

template<class T1, class T2> bool umin(T1& a, T2 b) { return a > b ? (a = b, true) : false; }
template<class T1, class T2> bool umax(T1& a, T2 b) { return a < b ? (a = b, true) : false; }
template<class T> void clear(T& a) { T().swap(a); }

const int N = 1e6 + 5;

int n, m, _, k;
int a[N] = {-1};

int main() {
    IOS;
    for (cin >> _; _; --_) {
        cin >> n >> k; m = 0;
        rep (i, 1, n) cin >> a[i], m += (a[i] != a[i - 1]);
        if (k == 1 && m > 1) cout << -1 << '
';
        else if (k == 1 || m == 1) cout << 1 << '
';
        else cout << (m - 1 + k - 2) / (k - 1) << '
';
    }
    return 0;
}

C

模拟

#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)
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef vector<int> VI;
typedef double db;
 
template<class T1, class T2> bool umin(T1& a, T2 b) { return a > b ? (a = b, true) : false; }
template<class T1, class T2> bool umax(T1& a, T2 b) { return a < b ? (a = b, true) : false; }
template<class T> void clear(T& a) { T().swap(a); }
 
const int N = 1e5 + 5;
 
int n, m, _, k;
ll a[N];
 
int main() {
    IOS;
    for (cin >> _; _; --_) {
        cin >> n >> m;
        rep(i, 1, n) cin >> a[i];
        ll l = 1, r = n, c = 1, d = 1;
        long double x = 0, y = m, t = 0;
        while (1) {
            if (l > r) {
                t += (y - x) / (c + d); break;
            }
            long double t1 = (a[l] - x) / c, t2 = (y - a[r]) / d;
            if (t1 == t2) t += t1, ++c, ++d, x = a[l++], y = a[r--];
            else if (t1 < t2) t += t1, ++c, x = a[l++], y -= d * t1;
            else t += t2, ++d, x += c * t2, y = a[r--];
        }
        cout << setiosflags(ios::fixed) << setprecision(15) << t << '
';
    }
    return 0;
}

D

dp, f[i], 表示向上 i 步后, 最多向右 走几步

怎么转移呢?

先考虑正好走不出去的, 及 a[i] - c[j] == x, 则 f[x] = max(f[x], b[i] - d[j] + 1)

最后倒序 f[i] = max(f[i], f[i + 1]),

找答案就好了

#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)
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef vector<int> VI;
typedef double db;
 
template<class T1, class T2> bool umin(T1& a, T2 b) { return a > b ? (a = b, true) : false; }
template<class T1, class T2> bool umax(T1& a, T2 b) { return a < b ? (a = b, true) : false; }
template<class T> void clear(T& a) { T().swap(a); }
 
const int N = 1e6 + 5;
 
int n, m, _, k;
int a[N], b[N], c[N], d[N], f[N];
 
int main() {
    IOS;
    cin >> n >> m;
    rep(i, 1, n) cin >> a[i] >> b[i];
    rep(i, 1, m) cin >> c[i] >> d[i];
    rep(i, 1, n)
        rep(j, 1, m)
            if (a[i] <= c[j] && b[i] <= d[j])
                umax(f[c[j] - a[i]], d[j] - b[i] + 1);
    int ans = 1e9;
    per(i, 1e6, 0) umax(f[i], f[i + 1]), umin(ans, i + f[i]);
    cout << ans;
    return 0;
}

E

题意, m 个 数组, 每个数组里每两个数(x, y, x < y)会连一条边(x, y)

每个数组连的边的颜色是不同的, 对于每个数组我们可以删除一个数(有代价), 相当于把这个数组对 这个数建的边都删了

删除完某些数组中的某些数以后, 使得建的所有边, 连成的环中, 边的颜色必须一样(或者不存在环)

思考发现, 如果两个数组都含有 x, y , 那么已经有个环了, 且两条边颜色不一样, 所以我们要从这连个数组中的一个删去x或y

当然删除代价最小的, 所以我们先按照代价排序, 从高到低

维护并查集, 每个数属于哪个数组集合就好了, 两次就删掉这个数

#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)
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef vector<int> VI;
typedef double db;

template<class T1, class T2> bool umin(T1& a, T2 b) { return a > b ? (a = b, true) : false; }
template<class T1, class T2> bool umax(T1& a, T2 b) { return a < b ? (a = b, true) : false; }
template<class T> void clear(T& a) { T().swap(a); }

const int N = 1e5 + 5;

int n, m, _, k, t;
int a[N], b[N], f[N << 1], high[N << 1], tot;
pair<int, PII> edge[N << 1];

int find(int x) { return f[x] == x ? x : f[x] = find(f[x]); }

bool unit(int x, int y) {
    x = find(x), y = find(y);
    if (x == y) return 0;
    if (high[x] > high[y]) f[y] = x;
    else if (high[x] < high[y]) f[x] = y;
    else f[y] = x, ++high[x];
    return 1;
}

int main() {
    IOS; cin >> m >> n; tot = 0;
    rep(i, 1, m) cin >> a[i];
    rep(i, 1, n) cin >> b[i];
    rep(i, 1, m)  for (cin >> k; k; --k) cin >> t, edge[++tot] = {a[i] + b[t], { i, m + t }};
    sort(edge + 1, edge + 1 + tot);
    rep(i, 1, m + n) f[i] = i, high[i] = 1;
    ll ans = 0;
    per(i, tot, 1)
        if (find(edge[i].se.fi) != find(edge[i].se.se)) unit(edge[i].se.fi, edge[i].se.se);
        else ans += edge[i].fi;
    cout << ans << '
';
    return 0;
}

F

反正没限制次数

最后最多两个不同的数, 无非是 [1, l] [l + 1, n] 这连个区间呗

什么情况可以一个数呢? 当然是 l - 1 + 1 == n - l - 1 + 1, 就是两个区长度相同

你操作 (1 + i, l + 1 + i) 并不就合并了吗?

由于 n 不一定是 2的次方, 所以操作一次 (1, (2^{k}) - 1) 一次 (n - (2^{k}) + 1, n) ((2^{k}) <= n && (2^{k + 1}) > n)

不就将 n 变成 ([1, n - 2^k] 和 [n - 2^k + 1, 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)
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef vector<int> VI;
typedef double db;

template<class T1, class T2> bool umin(T1& a, T2 b) { return a > b ? (a = b, true) : false; }
template<class T1, class T2> bool umax(T1& a, T2 b) { return a < b ? (a = b, true) : false; }
template<class T> void clear(T& a) { T().swap(a); }

const int N = 1e5 + 5;

int n, m, _, k, t;
vector<PII> ans;

void solve(int l, int r) {
    if (l == r) return;
    int mid = (l + r) >> 1;
    solve(l, mid); solve(mid + 1, r);
    rep (i, l, mid) ans.pb({ i, i - l + 1 + mid });
}

int main() {
    IOS; cin >> n;
    m = 1 << (int)log2(n);
    solve(1, 1 + m - 1); solve(n - m + 1, n);
    cout << ans.size() << '
';
    for (auto i : ans) cout << i.fi << ' ' << i.se << "
";
    return 0;
}
原文地址:https://www.cnblogs.com/2aptx4869/p/13757440.html