重复的数
题目来源:第十三届蓝桥杯 C++ C 组省赛 J 题——重复的数
主要思想——莫队,该思想参考学习地址 普通莫队算法。
对于若干区间范围内的询问,可以通过其他区间的情况调整范围来得到答案。为了能够最小化区间范围的修改次数,我们需要将所有询问进行排序,排序规则是按照l
所在块的编号为第一关键字,r
为第二关键字从小到大排序。
该死的Java,不懂在发什么电,同样的代码最后一个样例有时候能过,有时候会超时,波动超过1000ms就会超时。如果有哪位Java大佬发现了能够稳定通过的代码,记得评论区踢我一下!!
import java.io.*;
import java.util.Arrays;
public class Main {
static class Query implements Comparable<Query> {
public int id, l, r, k;
@Override
public int compareTo(Query other) {
if (this.l / maxn != other.l / maxn)
return Integer.compare(this.l, other.l);
return ((this.l / maxn) & 1) == 1 ? Integer.compare(this.r, other.r) : Integer.compare(other.r, this.r);
}
}
static final int N = 100003;
static int n, m, maxn;
static int[] arr = new int[N];
static int[] sum = new int[N];
static int[] cnt = new int[N];
static int[] ans = new int[N];
static Query[] q = new Query[N];
static StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
static int nextInt() throws IOException {
st.nextToken();
return (int) st.nval;
}
public static void main(String[] args) throws IOException {
n = nextInt();
for (int i = 1; i <= n; ++i) {
arr[i] = nextInt();
}
maxn = (int) Math.sqrt(n);
m = nextInt();
for (int i = 0; i < m; ++i) {
q[i] = new Query();
q[i].id = i;
q[i].l = nextInt();
q[i].r = nextInt();
q[i].k = nextInt();
}
Arrays.sort(q, 0, m);
int l = 1, r = 0;
for (int i = 0; i < m; ++i) {
while (l > q[i].l) {
--l;
sum[cnt[arr[l]]]--;
cnt[arr[l]]++;
sum[cnt[arr[l]]]++;
}
while (r < q[i].r) {
++r;
sum[cnt[arr[r]]]--;
cnt[arr[r]]++;
sum[cnt[arr[r]]]++;
}
while (l < q[i].l) {
sum[cnt[arr[l]]]--;
cnt[arr[l]]--;
sum[cnt[arr[l]]]++;
l++;
}
while (r > q[i].r) {
sum[cnt[arr[r]]]--;
cnt[arr[r]]--;
sum[cnt[arr[r]]]++;
r--;
}
ans[q[i].id] = sum[q[i].k];
}
for (int i = 0; i < m; ++i) {
System.out.println(ans[i]);
}
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.Arrays;
import java.util.Comparator;
public class Main {
static StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
static int nextInt() throws IOException {
st.nextToken();
return (int) st.nval;
}
static int n, m;
// res[i] 出现次数为 i 的个数
// cnt[i] 数字 i 出现的次数
static int[] arr, res, cnt, ans;
static int maxn;
static class Query {
public int l, r, k, id;
}
static Query[] queries;
static void increase(int index) {
res[cnt[arr[index]]]--;
cnt[arr[index]]++;
res[cnt[arr[index]]]++;
}
static void decrease(int index) {
res[cnt[arr[index]]]--;
cnt[arr[index]]--;
res[cnt[arr[index]]]++;
}
public static void main(String[] args) throws IOException {
res = new int[100003];
cnt = new int[100003];
n = nextInt();
arr = new int[n + 1];
maxn = (int) Math.sqrt(n);
for(int i = 1; i <= n; ++i) {
arr[i] = nextInt();
}
m = nextInt();
queries = new Query[m];
ans = new int[m];
for(int i = 0; i < m; ++i) {
queries[i] = new Query();
queries[i].id = i;
queries[i].l = nextInt();
queries[i].r = nextInt();
queries[i].k = nextInt();
}
Arrays.sort(queries, new Comparator<Query>() {
@Override
public int compare(Query o1, Query o2) {
if(o1.l / maxn != o2.l / maxn) {
return o1.l / maxn - o2.l / maxn;
}
return o1.r - o2.r;
}
});
int le = 1, ri = 0;
for(int i = 0; i < m; ++i) {
while (le > queries[i].l) {
// increase(--le);
--le;
res[cnt[arr[le]]]--;
cnt[arr[le]]++;
res[cnt[arr[le]]]++;
}
while(ri < queries[i].r) {
// increase(++ri);
++ri;
res[cnt[arr[ri]]]--;
cnt[arr[ri]]++;
res[cnt[arr[ri]]]++;
}
while(le < queries[i].l) {
// decrease(le++);
res[cnt[arr[le]]]--;
cnt[arr[le]]--;
res[cnt[arr[le]]]++;
le++;
}
while (ri > queries[i].r) {
// decrease(ri--);
res[cnt[arr[ri]]]--;
cnt[arr[ri]]--;
res[cnt[arr[ri]]]++;
ri--;
}
ans[queries[i].id] = res[queries[i].k];
}
for(int i = 0; i < m; ++i)
System.out.println(ans[i]);
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.Arrays;
import java.util.Comparator;
public class Main {
static StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
static int nextInt() throws IOException {
st.nextToken();
return (int) st.nval;
}
static int n, m;
// res[i] 出现次数为 i 的个数
// cnt[i] 数字 i 出现的次数
static int[] arr, res, cnt, ans;
static int maxn;
static class Query {
public int l, r, k, id;
}
static Query[] queries;
static void increase(int index) {
res[cnt[arr[index]]]--;
cnt[arr[index]]++;
res[cnt[arr[index]]]++;
}
static void decrease(int index) {
res[cnt[arr[index]]]--;
cnt[arr[index]]--;
res[cnt[arr[index]]]++;
}
public static void main(String[] args) throws IOException {
res = new int[100003];
cnt = new int[100003];
n = nextInt();
arr = new int[n + 1];
maxn = (int) Math.sqrt(n);
for(int i = 1; i <= n; ++i) {
arr[i] = nextInt();
}
m = nextInt();
queries = new Query[m];
ans = new int[m];
for(int i = 0; i < m; ++i) {
queries[i] = new Query();
queries[i].id = i;
queries[i].l = nextInt();
queries[i].r = nextInt();
queries[i].k = nextInt();
}
Arrays.sort(queries, new Comparator<Query>() {
@Override
public int compare(Query o1, Query o2) {
if(o1.l / maxn != o2.l / maxn) {
return o1.l / maxn - o2.l / maxn;
}
return o1.r - o2.r;
}
});
int le = 1, ri = 0;
for(int i = 0; i < m; ++i) {
while (le > queries[i].l) {
increase(--le);
}
while(ri < queries[i].r) {
increase(++ri);
}
while(le < queries[i].l) {
decrease(le++);
}
while (ri > queries[i].r) {
decrease(ri--);
}
ans[queries[i].id] = res[queries[i].k];
}
for(int i = 0; i < m; ++i)
System.out.println(ans[i]);
}
}
#include
using namespace std;
typedef long long ll;
const int N = 1e5 + 3;
#define endl "\n"
class Query
{
public:
int id, l, r, k;
} q[N];
int n, m, arr[N], sum[N], cnt[N], maxn, ans[N];
int cmp(Query q1, Query q2)
{
if (q1.l / maxn != q2.l / maxn)
return q1.l < q2.l;
return (q1.l / maxn) & 1 ? q1.r < q2.r : q1.r > q2.r;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n;
for (int i = 1; i <= n; ++i)
{
cin >> arr[i];
}
maxn = sqrt(n);
cin >> m;
for (int i = 0; i < m; ++i)
{
q[i].id = i;
cin >> q[i].l >> q[i].r >> q[i].k;
}
sort(q, q + m, cmp);
int l = 1, r = 0;
for (int i = 0; i < m; ++i)
{
while (l > q[i].l)
{
--l;
sum[cnt[arr[l]]]--;
cnt[arr[l]]++;
sum[cnt[arr[l]]]++;
}
while (r < q[i].r)
{
++r;
sum[cnt[arr[r]]]--;
cnt[arr[r]]++;
sum[cnt[arr[r]]]++;
}
while (l < q[i].l)
{
// decrease(le++);
sum[cnt[arr[l]]]--;
cnt[arr[l]]--;
sum[cnt[arr[l]]]++;
l++;
}
while (r > q[i].r)
{
sum[cnt[arr[r]]]--;
cnt[arr[r]]--;
sum[cnt[arr[r]]]++;
r--;
}
ans[q[i].id] = sum[q[i].k];
}
for (int i = 0; i < m; ++i)
cout << ans[i] << endl;
return 0;
}