Codeforces Round #716 (Div. 2) A ~ D 个人题解

补题链接:Here

1514A. Perfectly Imperfect Array

题意:给定长度为 \(n\)\(a\) 序列,请问是否存在子序列积不存在平方根

思路:子序列的话,一个元素也是子序列,那么只要存在某个元素不存在平方根即可

void solve() {
    int n;
    cin >> n;
    bool f = 1;
    while (n--) {
        int x, tmp;
        cin >> x;
        tmp = sqrt(x);
        if (tmp * tmp != x) f = 0;
    }
    cout << (!f ? "YES\n" : "NO\n");
}

1514B. AND 0, Sum Big

题面解释了那么多,本质就是 qpow(n,k) % mod

using ll      = long long;
const int mod = 1e9 + 7;
ll qpow(ll a, ll b) {
    ll ans = 1;
    a %= mod;
    for (; b; b >>= 1, a = a * a % mod)
        if (b & 1) ans = ans * a % mod;
    return ans;
}
void solve() {
    ll n, k;
    cin >> n >> k;
    cout << qpow(n, k) << "\n";
}

1514C. Product 1 Modulo N

题意:

现在,您得到Baby Ehab的第一句话:“给定整数n,找到乘积为1模n的最长子序列 \([1,2,…,n-1]\)。” 请解决问题。
如果可以通过删除某些(可能是全部)元素从a获得b,则序列b是数组a的子序列。 空子序列的乘积等于1。

思路:

首先想到 \(n = 2\) 时,仅有一种情况就是 \(1\)

然后在考虑 \(2\le n\) 时,维护 \(ans\) 。如果 \(i\)\(ans\) 互质则可以加入序列。

最后如果 \(ans = n - 1\) 最后一个数肯定不符合需要删去

int n;
void solve() {
    cin >> n;
    if (n == 2) {
        cout << "1\n1";
        return;
    }
    ll ans = 1;
    vector<int> v;
    for (int i = 1; i <= n; ++i) {
        if (__gcd(n, i) == 1) {
            v.push_back(i);
            ans = ans * i % n;
        }
    }
    if (ans == n - 1) v.pop_back();
    cout << v.size() << "\n";
    for (int x : v) cout << x << " ";
}

1514D. Cut and Stick

涉及区间修改查询问题肯定是线段树(树状数组)了

#include <bits/stdc++.h>
using namespace std;
using LL           = long long;
constexpr LL mod   = 1000000007;
constexpr int maxn = 300000 + 1;
struct Node {
    int cur, cnt;
    Node operator*(const Node &p) const {
        if (cur == p.cur) return {cur, cnt + p.cnt};
        if (cnt >= p.cnt) return {cur, cnt - p.cnt};
        return {p.cur, p.cnt - cnt};
    }
} t[maxn << 2];
int a[maxn];
vector<int> p[maxn];
#define ls (v << 1)
#define rs (ls | 1)
#define tm ((tl + tr) >> 1)
void build(int v, int tl, int tr) {
    if (tl == tr)
        t[v] = {a[tm], 1};
    if (tl < tr) {
        build(ls, tl, tm);
        build(rs, tm + 1, tr);
        t[v] = t[ls] * t[rs];
    }
}
Node query(int v, int tl, int tr, int L, int R) {
    if (tl >= L and tr <= R) return t[v];
    Node res = {0, 0};
    if (L <= tm) res = res * query(ls, tl, tm, L, R);
    if (R > tm) res = res * query(rs, tm + 1, tr, L, R);
    return res;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, q;
    cin >> n >> q;
    for (int i = 1; i <= n; i += 1) cin >> a[i];
    for (int i = 1; i <= n; i += 1) p[a[i]].push_back(i);
    build(1, 1, n);
    for (int i = 1; i <= q; i += 1) {
        int L, R;
        cin >> L >> R;
        auto v = query(1, 1, n, L, R);
        int x  = R - L + 1;
        int y  = v.cur;
        int z  = upper_bound(p[y].begin(), p[y].end(), R) - lower_bound(p[y].begin(), p[y].end(), L);
        cout << max(2 * z - x, 1) << "\n";
    }
    return 0;
}
posted @ 2021-04-20 19:01  RioTian  阅读(31)  评论(0编辑  收藏