SPOJ 3267:DQUERY 莫队

来源:互联网 发布:霸道总裁小说知乎 编辑:程序博客网 时间:2024/06/04 20:09

DQUERY - D-query

Given a sequence of n numbers a1, a2, ..., an and a number of d-queries. A d-query is a pair (i, j) (1 ≤ i ≤ j ≤ n). For each d-query (i, j), you have to return the number of distinct elements in the subsequence ai, ai+1, ..., aj.

Input

  • Line 1: n (1 ≤ n ≤ 30000).
  • Line 2: n numbers a1, a2, ..., an (1 ≤ ai ≤ 106).
  • Line 3: q (1 ≤ q ≤ 200000), the number of d-queries.
  • In the next q lines, each line contains 2 numbers i, j representing a d-query (1 ≤ i ≤ j ≤ n).

Output

  • For each d-query (i, j), print the number of distinct elements in the subsequence ai, ai+1, ..., aj in a single line.

Example

Input51 1 2 1 331 52 43 5Output323 
题意是查询区间内不同数字的种类。

莫队很经典的题,算每一个元素在区间内的贡献。

代码:

#pragma comment(linker, "/STACK:102400000,102400000")#pragma warning(disable:4996)  #include <iostream>#include <algorithm>#include <cstring>#include <vector>#include <string>#include <cstdio>#include <cmath>#include <queue>#include <stack>#include <set>#include <map>using namespace std;#define INF 0x3ffffffftypedef long long ll;const int mod = 1e9 + 7;const int maxn = 1e6 + 5;int n, q, bk;int val[30005], res[200005], num[maxn];struct no{int le;int ri;int id;}qu[200005];bool cmp(no n1, no n2){if (n1.le / bk == n2.le / bk){return n1.ri < n2.ri;}else{return n1.le / bk < n2.le / bk;}}void input(){int i, u, v;scanf("%d", &n);for (i = 1; i <= n; i++){scanf("%d", &val[i]);}scanf("%d", &q);for (i = 1; i <= q; i++){scanf("%d%d", &u, &v);qu[i].le = u;qu[i].ri = v;qu[i].id = i;}}void solve(){bk = sqrt(1.0*n);sort(qu + 1, qu + q + 1, cmp);int i, j, id, ans = 0;int pl = 1, pr = 0;for (i = 1; i <= q; i++){id = qu[i].id;if (qu[i].le == qu[i].ri){res[id] = 1;continue;}if (pr < qu[i].ri){for (j = pr + 1; j <= qu[i].ri; j++){if (num[val[j]] == 0){ans++;}num[val[j]]++;}}else{for (j = pr; j > qu[i].ri; j--){num[val[j]]--;if (num[val[j]] == 0){ans--;}}}pr = qu[i].ri;if (pl < qu[i].le){for (j = pl; j < qu[i].le; j++){num[val[j]]--;if (num[val[j]] == 0){ans--;}}}else{for (j = pl - 1; j >= qu[i].le; j--){if (num[val[j]] == 0){ans++;}num[val[j]]++;}}pl = qu[i].le;res[id] = ans;}for (i = 1; i <= q; i++){printf("%d\n", res[i]);}}int main() {//freopen("i.txt","r",stdin);//freopen("o.txt","w",stdout);input();solve();return 0;}



1 0
原创粉丝点击