补题链接: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
" : "NO
");
}
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) << "
";
}
1514C. Product 1 Modulo N
题意:
现在,您得到Baby Ehab的第一句话:“给定整数n,找到乘积为1模n的最长子序列 ([1,2,…,n-1])。” 请解决问题。
如果可以通过删除某些(可能是全部)元素从a获得b,则序列b是数组a的子序列。 空子序列的乘积等于1。
思路:
首先想到 (n = 2) 时,仅有一种情况就是 (1)
然后在考虑 (2le n) 时,维护 (ans) 。如果 (i) 与 (ans) 互质则可以加入序列。
最后如果 (ans = n - 1) 最后一个数肯定不符合需要删去
int n;
void solve() {
cin >> n;
if (n == 2) {
cout << "1
1";
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() << "
";
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) << "
";
}
return 0;
}