您的位置:首页 > 产品设计 > UI/UE

SPOJ 3267:DQUERY 莫队

2016-02-04 10:13 309 查看


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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: