Codeforces Round #705 (Div. 2)

Codeforces Round #705 (Div. 2)

A - Anti-knapsack

模拟

const int N = 1e5 + 5;
 
int n, m, _, k, cas;
int v[N];
 
int main() {
    IOS;
    for (cin >> _; _; --_) {
        cin >> n >> m; VI a;
        rep (i, 1, n) v[i] = 1; v[m] = 0;
        per (i, n, 1) if (v[i]) {
            a.pb(i);
            if (i < m) v[m - i] = 0;
        }
        cout << a.size() << '
';
        for (auto &i : a) cout << i << ' '; cout << '
';
    }
    return 0;
}

B - Planet Lapituletti

模拟

const int N = 1e5 + 5;
 
int n, m, _, k, cas;
int a[N], c[N];
 
int main() {
    a[0]=1; a[1]=1; a[2]=1;
    a[5]=1; a[8]=1;
    c[0]=0; c[1]=1; c[2]=5;
    c[5]=2; c[8]=8;
    for (read(_); _; --_) {
        int h, m, hh, mm, nowh, nowm; read(h, m, hh, mm);
        bool f = 0;
        rep (i, hh, h - 1) {
            for(int j = (i == hh ? mm : 0); !f && j < m; ++j) {
                if(a[i % 10] && a[i / 10] && a[j % 10] && a[j / 10]) {
                    nowh = c[j / 10] + c[j % 10] * 10;
                    nowm = c[i / 10] + c[i % 10] * 10;
                    if (nowh < h && nowm <m) printf("%02d:%02d
", i, j), f = 1;
                }
            }
            if (f) break;
        }
        if (!f) printf("00:00
");
    }
    return 0;
}

C - K-beautiful Strings

n % k != 0 无解

如果 s 本身就是, 直接输出

其他情况,无非是在距离 n 最近的位置 t[i] > s[i], 1 + i <= j <= n 之间插入a 和剩余字符

1 <= j < i, t[i] = s[i]

const int N = 1e5 + 5;
 
int n, m, _, k, cas;
int a[26];
char s[N];
 
bool work(int res) {
    int c = 0;
    rep(i, 0, 25) if (a[i] % k) c += k - a[i] % k;
    int cur = n - res - c;
    if (cur >= 0 && cur % k == 0) {
	rep(i, 1, res) cout << char(s[i]);
	rep(i, 1, cur) cout << 'a';
	rep(i, 0, 25) if (a[i] % k)
	    rep(j, 1, k - a[i] % k) cout << (char)(i + 'a');
	    cout << '
'; return 1;
	}
    return 0;
}
 
int main() {
    IOS;
    for (cin >> _; _; --_) {
	cin >> n >> k >> s + 1; memset(a, 0, sizeof a);
	if (n % k) { cout << -1 << '
'; continue; }
	rep(i, 1, n) ++a[s[i] - 'a']; bool f = 1;
	rep(i, 0, 25) if (a[i] % k) f = 0;
	if (f) { cout << s + 1 << '
'; continue; }
	per(i, n, 1) {
	    --a[s[i] - 'a']; f = 0;
	    rep(j, s[i] - 'a' + 1, 25) {
	        ++a[j], s[i] = 'a' + j;
		if (work(i)) { f = 1; break; }
		--a[j];
	    }
	    if (f) break;
	}
    }
    return 0;
}

D - GCD of an Array

人均会动态开点是吧

动态线段树维护 1~n 位置最少有多少个质数 pri[i]

每次操作(最初把每个位置视为 1)最多有7个不同的质数, 复杂度为 (2 * 7 * n * log(n))

map也行, 代码放下面了

const int N = 2e5 + 5, M = 17984 + 5, mod = 1e9 + 7;
 
struct BIT {
    struct node { int l = 0, r = 0, val = 0; } tr[20000000];
    int rt[N], tot;
    void push_up(int rt) { 
        tr[rt].val = min(tr[tr[rt].l].val, tr[tr[rt].r].val);
    }
    void change(int& p, int l, int r, int d, int k) {
        if (!p) p = ++tot;
        if (l == r) { tr[p].val += k; return; }
        int mid = l + r >> 1;
        if (d <= mid) change(tr[p].l, l, mid, d, k);
        else change(tr[p].r, mid + 1, r, d, k);
        push_up(p);
    }
    int ask(int x) { return tr[x].val; }
} bit;
 
int n, m, _, k, cas;
int pri[N], tot;
bool v[N];
 
void init(int n) {
    rep(i, 2, n) {
        if (!v[i]) pri[++tot] = i;
        rep(j, 1, tot) {
            if (i > n / pri[j]) break;
            v[i * pri[j]] = 1;
            if (i % pri[j] == 0) break;
        }
    }
}
 
ll qpow(ll a, ll b) {
    ll ans = 1;
    for (; b; b >>= 1, a = a * a % mod) if (b & 1) ans = ans * a % mod;
    return ans;
}
 
int main() {
    IOS; cin >> n >> m; init(2e5); ll ans = 1;
    rep(i, 1, n) {
        cin >> k;
        for (int j = 1; j <= tot && pri[j] <= k / pri[j]; ++j) if (k % pri[j] == 0) {
            int cnt = 0;
            while (k % pri[j] == 0) k /= pri[j], ++cnt;
            bit.change(bit.rt[pri[j]], 1, n, i, cnt);
        }
        if (k > 1) bit.change(bit.rt[k], 1, n, i, 1);
    }
    rep(i, 1, tot) ans = ans * qpow(pri[i], bit.ask(bit.rt[pri[i]])) % mod;
    rep(i, 1, m) {
        int x, k; cin >> x >> k;
        for (int j = 1; j <= tot && pri[j] <= k / pri[j]; ++j) if (k % pri[j] == 0) {
            int cnt = 0, res = bit.ask(bit.rt[pri[j]]);
            while (k % pri[j] == 0) k /= pri[j], ++cnt;
            bit.change(bit.rt[pri[j]], 1, n, x, cnt);
            ans = ans * qpow(pri[j], bit.ask(bit.rt[pri[j]]) - res) % mod;
        }
        if (k > 1) {
            int res = bit.ask(bit.rt[k]);
            bit.change(bit.rt[k], 1, n, x, 1);
            ans = ans * qpow(k, bit.ask(bit.rt[k]) - res) % mod;
        }
        cout << ans << '
';
    }
    return 0;
}
const int N = 2e5 + 5, mod = 1e9 + 7;
 
int n, m, _, k, cas;
int pri[N], tot;
multiset<int> st[N];
unordered_map<int, int> h[N];
bool v[N];
 
void init(int n) {
    rep(i, 2, n) {
        if (!v[i]) pri[++tot] = i;
        rep(j, 1, tot) {
            if (i > n / pri[j]) break;
            v[i * pri[j]] = 1;
            if (i % pri[j] == 0) break;
        }
    }
}
 
ll qpow(ll a, ll b) {
    ll ans = 1;
    for (; b; b >>= 1, a = a * a % mod) if (b & 1) ans = ans * a % mod;
    return ans;
}
 
int main() {
    IOS; cin >> n >> m; init(2e5); ll ans = 1;
    rep(i, 1, n) {
        cin >> k;
        for (int j = 1; j <= tot && pri[j] <= k / pri[j]; ++j) if (k % pri[j] == 0) {
            int cnt = 0;
            while (k % pri[j] == 0) k /= pri[j], ++cnt;
            st[pri[j]].insert(cnt); h[i][pri[j]] = cnt;
        }
        if (k > 1)  st[k].insert(1), h[i][k] = 1;
    }
    rep(i, 1, tot) if (st[pri[i]].size() == n)
        ans = ans * qpow(pri[i], *st[pri[i]].begin()) % mod;
    rep(i, 1, m) {
        int x, k; cin >> x >> k;
        for (int j = 1; j <= tot && pri[j] <= k / pri[j]; ++j) if (k % pri[j] == 0) {
            int cnt = 0, res = st[pri[j]].size() == n ? *st[pri[j]].begin() : 0;
            if (h[x].count(pri[j])) st[pri[j]].erase(st[pri[j]].find(h[x][pri[j]]));
            while (k % pri[j] == 0) k /= pri[j], ++cnt;
            h[x][pri[j]] += cnt; st[pri[j]].insert(h[x][pri[j]]);
            if (st[pri[j]].size() == n) ans = ans * qpow(pri[j], *st[pri[j]].begin() - res) % mod;
        }
        if (k > 1) {
            int res = st[k].size() == n ? *st[k].begin() : 0;
            if (h[x].count(k)) st[k].erase(st[k].find(h[x][k]));
            h[x][k] += 1; st[k].insert(h[x][k]);
            if (st[k].size() == n) ans = ans * qpow(k, *st[k].begin() - res) % mod;
        }
        cout << ans << '
';
    }
    return 0;
}
原文地址:https://www.cnblogs.com/2aptx4869/p/14493962.html