1188 - Fast Queries
PDF (English) | Statistics | Forum |
Time Limit: 3 second(s) | Memory Limit: 64 MB |
Given an array of N integers indexed from 1 to N, and q queries, each in the form i j, you have to find the number of distinct integers from index i to j (inclusive).
Input
Input starts with an integer T (≤ 5), denoting the number of test cases.
The first line of a case is a blank line. The next line contains two integers N (1 ≤ N ≤ 105), q (1 ≤ q ≤ 50000). The next line contains N space separated integers forming the array. There integers range in [0, 105].
Each of the next q lines will contain a query which is in the form i j (1 ≤ i ≤ j ≤ N).
Output
For each test case, print the case number in a single line. Then for each query you have to print a line containing number of distinct integers from index i to j.
Sample Input |
Output for Sample Input |
1 8 5 1 1 1 2 3 5 1 2 1 8 2 3 3 6 4 5 4 8 |
Case 1: 4 1 4 2 4 |
Note
Dataset is huge. Use faster I/O methods.
题目链接:LighOJ 1188
莫队大法好,看到n的范围是1e5也就直接上莫队了,用vis记录数字出现次数,显然对于区间的增减进行更新vis,若缩小区间导致vis[val]为0则说明少了一个数,反之为1则就是增加一个数,700MS还可以,另外一种不同的做法是用树状数组更新统计。
代码:
#include<iostream> #include<algorithm> #include<cstdlib> #include<sstream> #include<cstring> #include<bitset> #include<cstdio> #include<string> #include<deque> #include<stack> #include<cmath> #include<queue> #include<set> #include<map> using namespace std; #define INF 0x3f3f3f3f #define CLR(x,y) memset(x,y,sizeof(x)) #define LC(x) (x<<1) #define RC(x) ((x<<1)+1) #define MID(x,y) ((x+y)>>1) typedef pair<int,int> pii; typedef long long LL; const double PI=acos(-1.0); const int N=100010; const int M=50010; struct info { int l,r; int id,b; bool operator<(const info &t)const { if(b==t.b) return r<t.r; return b<t.b; } }; info Q[M]; int arr[N]; int vis[N]; int ans[M]; int main(void) { int tcase,i,j; int n,m,l,r; scanf("%d",&tcase); for (int q=1; q<=tcase; ++q) { scanf("%d%d",&n,&m); for (i=1; i<=n; ++i) scanf("%d",&arr[i]); int unit=(int)sqrt(n); for (i=1; i<=m; ++i) { scanf("%d%d",&Q[i].l,&Q[i].r); Q[i].id=i; Q[i].b=Q[i].l/unit; } sort(Q+1,Q+1+m); CLR(vis,0); int L=1,R=0; int temp=0; for (i=1; i<=m; ++i) { while (L>Q[i].l) { --L; ++vis[arr[L]]; if(vis[arr[L]]==1) ++temp; } while (L<Q[i].l) { --vis[arr[L]]; if(vis[arr[L]]==0) --temp; ++L; } while (R>Q[i].r) { --vis[arr[R]]; if(vis[arr[R]]==0) --temp; --R; } while (R<Q[i].r) { ++R; ++vis[arr[R]]; if(vis[arr[R]]==1) ++temp; } ans[Q[i].id]=temp; } printf("Case %d:\n",q); for (i=1; i<=m; ++i) printf("%d\n",ans[i]); } return 0; }