Just do it
时间限制:
2000 ms | 内存限制:
65535 KB
难度:
4
-
描述
-
蚂蚁终于忍受不了宇宙总部要回地球了,它叮嘱我不要再编它的故事了,
有啥事直接说,有啥问题直接问就好了,它相信大家都能替他解决的,
毕竟都解决了不少问题了。
好,这次就直接说问题
求一个序列的某个区间中出现了多少不相同的数字。对于一个序列会询问很多很多次。
-
输入
-
第一行一个整数T,表示T组数据 (T < 10)
每组数据第1行一个整数 N 表示第2行有 N 个整数ai (N <= 30000, 1 <= ai <= 1000000)
第3行一个整数 M 表示有 M 次询问的区间(M <= 200000)
第4行开始往后M行每行两个整数a b,表示询问的区间[a,b] (1 <= a <= b <= n)
输出
-
每组数据M行,输出表示结果
样例输入
-
1 5 1 1 2 1 3 3 1 5 2 4 3 5
样例输出
-
3 2 3
提示
Huge inpiut ,please use scanf to read.
解题思路:区间问题,而且又没有更新,莫队算法正适合处理这类情况,如果比较熟悉莫队的话就是水题啦。。
#include<iostream> #include<cstdio> #include<cstring> #include<map> #include<cmath> #include<algorithm> using namespace std; const int maxn = 300005; const int maxm = 200005; int n,m,block,a[maxn],res[maxm]; int Map[1000005]; struct Node { int l,r,id; bool operator < (const Node &rhs) const { if(l / block == rhs.l / block) return r / block < rhs.r / block; return l / block < rhs.l / block; } }q[maxm]; void solve() { block = sqrt(n + 0.5); sort(q+1,q+1+m); int ans = 0,l = 1,r = 0; for(int i = 1; i <= m; i++) { if(q[i].l == q[i].r) { res[q[i].id] = 1; continue; } while(l < q[i].l) { Map[a[l]]--; if(Map[a[l]] == 0) ans--; l++; } while(l > q[i].l) { l--; Map[a[l]]++; if(Map[a[l]] == 1) ans++; } while(r < q[i].r) { r++; Map[a[r]]++; if(Map[a[r]] == 1) ans++; } while(r > q[i].r) { Map[a[r]]--; if(Map[a[r]] == 0) ans--; r--; } res[q[i].id] = ans; } for(int i = 1; i <= m; i++) printf("%d\n",res[i]); } int main() { int t; scanf("%d",&t); while(t--) { memset(Map,0,sizeof(Map)); scanf("%d",&n); for(int i = 1; i <= n; i++) scanf("%d",&a[i]); scanf("%d",&m); for(int i = 1; i <= m; i++) { scanf("%d %d",&q[i].l,&q[i].r); q[i].id = i; } solve(); } return 0; }
-
第一行一个整数T,表示T组数据 (T < 10)