java代码
莫队 + 类排序 + 双指针 + 快读
板题
O(n*sqrt(n))
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.StreamTokenizer; import java.util.Arrays; import java.util.Scanner;
public class query { static int n, m, a[]; static int cnt[], ans[], bein[], l = 1, r, now;
static class Node {
int l, r, id;
Node(int l, int r, int id) {
this.l = l;
this.r = r;
this.id = id;
}
}
static int ceil(double num) {
return (int) Math.ceil(num);
}
static int[] createBein(int n) {
int sqrtN = (int) Math.sqrt(n);
int size = (sqrtN + 1) * sqrtN; // 保证足够的容量来存储划分的区块
int[] bein = new int[size + 1]; // 多加1以防止n是完全平方数时边界问题
for (int i = 1; i <= sqrtN; i++) {
for (int j = (i - 1) * sqrtN + 1; j <= Math.min(i * sqrtN, n); j++) { // 需要确保j不超过n
bein[j] = i;
}
}
return bein;
}
static int compare(Node a, Node b) {
return bein[a.l] == bein[b.l] ? a.r - b.r : bein[a.l] - bein[b.l];
}
static void add(int x) {
if (cnt[a[x]] == 0)
++now;
++cnt[a[x]];
}
static void del(int x) {
--cnt[a[x]];
if (cnt[a[x]] == 0)
--now;
}
static void print(int x) {
if (x / 10 != 0)
print(x / 10);
System.out.print((char) ('0' + x % 10));
}
public static void main (String[] args) throws IOException{
Scanner sc = new Scanner(System.in);
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
PrintWriter cout = new PrintWriter(new OutputStreamWriter(System.out));
in.nextToken();
n = (int) in.nval;
a = new int[n + 1];
cnt = new int[1000010];
ans = new int[m + 1];
bein = createBein(n);
for (int i = 1; i <= n; ++i) {
in.nextToken();
a[i] = (int) in.nval;
}
in.nextToken();
m = (int) in.nval;
Node[] q = new Node[m + 1];
for (int i = 1; i <= m; ++i) {
in.nextToken();
q[i] = new Node((int)in.nval, (int)in.nval, i);
}
Arrays.sort(q, 1, m + 1, (o1, o2) -> compare(o1, o2));
for (int i = 1; i <= m; ++i) {
while (l < q[i].l)
del(l++);
while (l > q[i].l)
add(--l);
while (r < q[i].r)
add(++r);
while (r > q[i].r)
del(r--);
ans[q[i].id] = now;
}
for (int i = 1; i <= m; ++i) {
cout.println(ans[i]);
}
cout.flush();
}
}