题目背景
无
题目描述
HH 有一串由各种漂亮的贝壳组成的项链。HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义。HH 不断地收集新的贝壳,因此,他的项链变得越来越长。有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同的贝壳?这个问题很难回答……因为项链实在是太长了。于是,他只好求助睿智的你,来解决这个问题。
输入输出格式
输入格式:
第一行:一个整数N,表示项链的长度。
第二行:N 个整数,表示依次表示项链中贝壳的编号(编号为0 到1000000 之间的整数)。
第三行:一个整数M,表示HH 询问的个数。
接下来M 行:每行两个整数,L 和R(1 ≤ L ≤ R ≤ N),表示询问的区间。
输出格式:
M 行,每行一个整数,依次表示询问对应的答案。
********************************************************
莫队模板题,也没啥好说的,同学们可以到 http://blog.csdn.net/wzw1376124061/article/details/67640410
去学习一下
*****************************************
#include<cmath> #include<cstdio> #include<algorithm> #define maxn 200001 using namespace std; struct goio { int l,r; int id; }note[maxn]; int visited[maxn * 5]; int print[maxn]; int hanin[50001]; int lc = 1;int rc = 0;int ans = 0;int biaozhun; int read() { int num = 0; char c = getchar(); int f = 1; while(c < '0'||c > '9') { if(c == '-')f = -1; c = getchar(); } while(c >= '0' && c <= '9') { num *= 10; num += c - '0'; c = getchar(); } return num * f; } void add(int x) { visited[hanin[x]]++; ans += (visited[hanin[x]] == 1); } void Upout(int x) { visited[hanin[x]]--; ans -= (visited[hanin[x]] == 0); } bool cmp(const goio &a,const goio &b) { int aa = a.l/biaozhun; int bb = b.l/biaozhun; if(aa == bb)return a.r < b.r; else return aa < bb; } int main() { int n = read(); biaozhun = sqrt(n); for(int i = 1;i <= n;i ++) { hanin[i] = read(); } int m = read(); for(int i = 1;i <= m;i ++) { note[i].l = read(); note[i].r = read(); note[i].id = i; } sort(note + 1,note + m + 1,cmp); for(int i = 1;i <= m;i ++) { int l = note[i].l; int r = note[i].r; while(lc < l)Upout(lc),lc++; while(lc > l)lc--,add(lc); while(rc < r)rc++,add(rc); while(rc > r)Upout(rc),rc--; print[note[i].id] = ans; } for(int i = 1;i <= m;i ++) printf("%d\n",print[i]); return 0; }