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
Input 5 1 1 2 1 3 3 1 5 2 4 3 5 Output 3 2 3
莫队很经典的题,算每一个元素在区间内的贡献。
代码:
#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 0x3fffffff
typedef 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;
}