Educational Codeforces Round 91 (Rated for Div. 2)

吐了, 暑假没了, 开下学期的课, cf基本按时打不了

打不了的都是上分场

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 IO ios::sync_with_stdio(0); cin.tie(0);
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef vector<int> VI;
typedef double db;
 
const int N = 2e5 + 5;
 
int n, m, _, k;
int a[1005], b[1005];
 
int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    for (cin >> _; _; --_) {
        cin >> n;
        bool fa = 0, fb = 0;
        int x = 0, y = 0, z = 0;
        PII mi = { 1e9, 0 };
        rep (i, 1, n) {
            cin >> a[i];
            b[i] = 0;
            if (mi.fi < a[i]) b[i] = mi.se;
            if (a[i] < mi.fi) mi = { a[i], i }; 
        }
 
        mi = { 1e9, n };
        per (i, n, 1) {
            if (mi.fi < a[i] && b[i]) {
                x = b[i], y = i, z = mi.se;
                break;
            } 
            if (mi.fi > a[i]) mi = { a[i], i };
        }
 
        if (x) cout << "YES
" << x << ' ' << y << ' ' << z << '
';
        else cout << "NO
";
    }
    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)
#define IO ios::sync_with_stdio(0); cin.tie(0);
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef vector<int> VI;
typedef double db;
 
const int N = 2e5 + 5;
 
int n, m, _, k;
 
int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    for (cin >> _; _; --_) {
        string s; cin >> s;
        int a = 0, b = 0, c = 0;
        rep (i, 0, s.size() - 1)
            if (s[i] == 'R') ++a;
            else if (s[i] == 'P') ++b;
            else ++c; 
 
        char d = (a >= b && a >= c) ? 'P' : (b >= a && b >= c) ? 'S' : 'R';
        rep (i, 1, s.size()) cout << d;
        cout << '
';
    }
    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 IO ios::sync_with_stdio(0); cin.tie(0);
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef vector<int> VI;
typedef double db;
 
const int N = 1e5 + 5;
 
int n, m, _, k;
int a[N], b[N];
 
int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    for (cin >> _; _; --_) {
        cin >> n >> m;
        rep (i, 1, n) cin >> a[i], b[i] = (m - 1) / a[i] + 1;
 
        sort(b + 1, b + 1 + n);
 
        int ans = 0, ls = 0;
        rep (i, 1, n) 
            if (b[i] <= i - ls) ++ans, ls = i;
        
        cout << ans << '
';
    }
    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)
#define IO ios::sync_with_stdio(0); cin.tie(0);
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef vector<int> VI;
typedef double db;
 
const int N = 2e5 + 5;
 
int n, m, _;
int a[N], b[N], c[N];
ll x, y, k;
 
ll work(int l, int r, int c) {
    if (l > r) return 0;
 
    bool cnt = 0;
    rep(i, l, r)
        if (a[i] > c) { cnt = 1; break; }
 
    if (cnt && r - l + 1 < k) return -1;
 
    if (x > y * k) {
        if (cnt == 0) return y * (r - l + 1);
        return x + y * (r - l + 1 - k);
    }
 
    return (ll)(r - l + 1) / k * x + (ll)(r - l + 1) % k * y;
}
 
int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m >> x >> k >> y;
 
    c[m + 1] = b[n + 1] = n + 1;
    ll ans = 0;
    int ls = 0;
    bool f = 1;
 
    rep(i, 1, n) cin >> a[i], b[a[i]] = i;
    rep(i, 1, m + 1) {
        if (i <= m) cin >> c[i];
        if (f == 0) continue;
        if (!b[c[i]] || b[c[i]] <= ls) { f = 0; continue; }
 
        ll res = work(ls + 1, b[c[i]] - 1, i <= m ? max(c[i - 1], c[i]) : c[i - 1]);
        if (res == -1) { f = 0; continue; }
        ans += res; ls = b[c[i]];
    }
 
    if (f) cout << ans;
    else cout << -1;
    return 0;
}

E

呜呜呜, vector超时了

就是每次移动的时候, 要O(n),, 那为什么不用map呢, 查找和插入都是 logn

vector版, T 第32个数据

#include <bits/stdc++.h>
#define all(n) (n).begin(), (n).end()
#define se second
#define fi first
#define pb emplace_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 IO ios::sync_with_stdio(0); cin.tie(0);
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef vector<int> VI;
typedef double db;
 
const int N = 2e5 + 5;
 
int n, m, _, k;
int v[N];
vector<PII> st[N];
 
inline void work(int x, int y) {
    if (st[y].empty()) return;
    if (st[x].empty()) {
        st[x] = st[y];
        vector<PII>().swap(st[y]);
        return;
    }
 
    int i = 0, j = 0;
    vector<PII>().swap(st[0]);
    if (st[x][0] < st[y][0]) st[0].pb(st[x][i++]);
    else st[0].pb(st[y][j++]);
 
    for (; i < st[x].size() || j < st[y].size();) {
        if (j == st[y].size() || (i < st[x].size() && st[x][i] < st[y][j])) {
            if (st[x][i].fi == st[0].back().se + 1) st[0].back().se = st[x][i++].se, --k;
            else st[0].pb(st[x][i++]);
        }
        else {
            if (st[y][j].fi == st[0].back().se + 1) st[0].back().se = st[y][j++].se, --k;
            else st[0].pb(st[y][j++]);
        }
    }
 
    st[x] = st[0];
    vector<PII>().swap(st[y]);
}
 
int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m; k = n;
    rep(i, 1, n) {
        int x; cin >> x;
        if (!st[x].empty() && st[x].back().se == i - 1) 
            st[x].back().se = i, --k;
        else st[x].pb(PII{ i, i });
    }
 
    cout << k - 1 << '
';
 
    rep(i, 2, m) {
        int a, b; cin >> a >> b;
        work(a, b);
        cout << k - 1 << '
';
    }
    return 0;
}

map, 红黑树nb

#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 IO ios::sync_with_stdio(0); cin.tie(0);
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef vector<int> VI;
typedef double db;
 
const int N = 2e5 + 5;
 
int n, m, _, k;
int v[N];
map<int, int> st[N];
 
int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m; k = n;
    st[0][1] = -1;
    rep (i, 1, n) {
        int x; cin >> x;
        if (!st[x].empty() && st[x].rbegin()->se + 1 == i)
            st[x][st[x].rbegin()->fi] = i, --k;
        else st[x][i] = i;
    }
 
    cout << k - 1 << '
';
 
    rep (i, 2, m) {
        int a, b; cin >> a >> b;
        if (st[a].size() < st[b].size()) swap(st[a], st[b]);
 
        for (PII p : st[b]) {
            map<int, int>::iterator itb = st[a].upper_bound(p.fi), ita;
 
            if (itb != st[a].begin()) ita = itb, --ita;
            else ita = st[0].begin();
 
            if (itb != st[a].end()) 
                if (itb->fi == p.se + 1)
                    p.se = itb->se, --k, st[a].erase(itb);
 
            if (ita->se + 1 != p.fi) st[a][p.fi] = p.se;
            else st[a][ita->fi] = p.se, --k;
            //|| (ita->se) + 1 != p.fi
        }
 
        cout << k - 1 << '
';
        map<int, int>().swap(st[b]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/2aptx4869/p/13356395.html