洛谷 P3709 大爷的字符串题 解题报告
洛谷 P3709 大爷的字符串题 解题报告
[link](P3709 大爷的字符串题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn))
Solutions
我们手玩一下,可将题意转化为 求区间众数的出现次数。
我们贪心地想,最优情况一定是将原数列分割成几个单调递增的数列,数列个数即为 众数出现次数减去数列长度。
Details
注意题面的\(rp\)是从0开始减的,所以输出\(-ans[i]\)。
Code
P3709:
#include <bits/stdc++.h>
using namespace std;
const int MN = 2e5 + 5;
int n, m, block, sum;
int a[MN], date[MN], cnt[MN], num[MN], ans[MN];
struct Query {
int l, r, id;
bool operator < (const Query &x) const {
return l / block != x.l / block ? l < x.l : l / block & 1 ? r < x.r : r > x.r;
}
} q[MN];
void add(int x) {
num[cnt[x]]--, cnt[x]++, num[cnt[x]]++;
while (num[sum + 1]) sum++;
}
void del(int x) {
num[cnt[x]]--, cnt[x]--, num[cnt[x]]++;
while (!num[sum]) sum--;
}
signed main() {
ios::sync_with_stdio(false), cin.tie(0);
cin >> n >> m; block = sqrt(n);
for (int i = 1; i <= n; ++i) cin >> a[i], date[i] = a[i];
sort(date + 1, date + 1 + n);
int qwq = unique(date + 1, date + 1 + n) - date - 1;
for (int i = 1; i <= n; ++i) a[i] = lower_bound(date + 1, date + 1 + qwq, a[i]) - date;
for (int i = 1; i <= m; ++i) {
cin >> q[i].l >> q[i].r;
q[i].id = i;
}
sort(q + 1, q + 1 + m);
for (int i = 1, l = 1, r = 0; i <= m; ++i) {
while (l > q[i].l) add(a[--l]);
while (r < q[i].r) add(a[++r]);
while (l < q[i].l) del(a[l++]);
while (r > q[i].r) del(a[r--]);
ans[q[i].id] = sum;
}
for (int i = 1; i <= m; ++i) cout << -ans[i] << '\n';
return 0;
}
CF1514D
#include <bits/stdc++.h>
using namespace std;
const int MN = 3e5 + 5;
int n, m, block, sum;
int a[MN], date[MN], cnt[MN], num[MN], ans[MN];
struct Query {
int l, r, id;
bool operator < (const Query &x) const {
return l / block != x.l / block ? l < x.l : l / block & 1 ? r < x.r : r > x.r;
}
} q[MN];
void add(int x) {
num[cnt[x]]--, cnt[x]++, num[cnt[x]]++;
while (num[sum + 1]) sum++;
}
void del(int x) {
num[cnt[x]]--, cnt[x]--, num[cnt[x]]++;
while (!num[sum]) sum--;
}
signed main() {
ios::sync_with_stdio(false), cin.tie(0);
cin >> n >> m; block = sqrt(n);
for (int i = 1; i <= n; ++i) cin >> a[i], date[i] = a[i];
sort(date + 1, date + 1 + n);
int qwq = unique(date + 1, date + 1 + n) - date - 1;
for (int i = 1; i <= n; ++i) a[i] = lower_bound(date + 1, date + 1 + qwq, a[i]) - date;
for (int i = 1; i <= m; ++i) {
cin >> q[i].l >> q[i].r;
q[i].id = i;
}
sort(q + 1, q + 1 + m);
for (int i = 1, l = 1, r = 0; i <= m; ++i) {
while (l > q[i].l) add(a[--l]);
while (r < q[i].r) add(a[++r]);
while (l < q[i].l) del(a[l++]);
while (r > q[i].r) del(a[r--]);
ans[q[i].id] = sum * 2 - (q[i].r - q[i].l + 1);
}
for (int i = 1; i <= m; ++i) cout << max(1, ans[i]) << '\n';
return 0;
}
Data
莫队求区间众数:莫队求区间众数 D. Cut and Stick - EchoZQN - 博客园 (cnblogs.com)
题意转化思路参考:题解 P3709 【大爷的字符串题】 - 中国飞鱼 的博客 - 洛谷博客 (luogu.com.cn)
本文来自博客园,作者:zjsqwq,转载请注明原文链接:https://www.cnblogs.com/zjsqwq/p/16390257.html

浙公网安备 33010602011771号