bzoj 5016: [Snoi2017]一个简单的询问(莫队)

5016: [Snoi2017]一个简单的询问

Time Limit: 30 Sec   Memory Limit: 512 MB
Submit: 87   Solved: 64
[ Submit][ Status][ Discuss]

Description

给你一个长度为N的序列ai,1≤i≤N和q组询问,每组询问读入l1,r1,l2,r2,需输出
get(l,r,x)表示计算区间[l,r]中,数字x出现了多少次。

Input

第一行,一个数字N,表示序列长度。
第二行,N个数字,表示a1~aN
第三行,一个数字Q,表示询问个数。
第4~Q+3行,每行四个数字l1,r1,l2,r2,表示询问。
N,Q≤50000
N1≤ai≤N
1≤l1≤r1≤N
1≤l2≤r2≤N
注意:答案有可能超过int的最大值

Output

对于每组询问,输出一行一个数字,表示答案

Sample Input

5
1 1 1 1 1
2
1 2 3 4
1 1 4 4

Sample Output

4
1


bzoj 5016: [Snoi2017]一个简单的询问(莫队)_第1张图片

把每个问题拆成四个问题,这样就可以O(1)转,直接莫队吧


#include
#include
#include
using namespace std;
#define LL long long
int pos[50005];
typedef struct Que
{
	int l, r;
	int c, id;
	bool operator < (const Que &b) const
	{
		if(pos[l]s[i].l)
			val -= sr[a[L]], sl[a[L--]]--;
		while(Rs[i].r)
			val -= sl[a[R]], sr[a[R--]]--;
		ans[s[i].id] += val*s[i].c;
	}
	for(i=1;i<=q;i++)
		printf("%lld\n", ans[i]);
	return 0;
}
/*
5
1 1 1 1 1
7
1 5 1 5
2 2 1 1
2 4 3 5
1 3 2 4
1 3 3 5
1 4 2 5
1 5 5 5
*/


你可能感兴趣的:(#,分治与分块)