Little Elephant and Array CodeForces - 220B (莫队)
The Little Elephant loves playing with arrays. He has array a, consisting of npositive integers, indexed from 1 to n. Let's denote the number with index i as ai.
Additionally the Little Elephant has m queries to the array, each query is characterised by a pair of integers lj and rj (1 ≤ lj ≤ rj ≤ n). For each query lj, rjthe Little Elephant has to count, how many numbers x exist, such that number xoccurs exactly x times among numbers alj, alj + 1, ..., arj.
Help the Little Elephant to count the answers to all queries.
Input
The first line contains two space-separated integers n and m (1 ≤ n, m ≤ 105) — the size of array a and the number of queries to it. The next line contains n space-separated positive integers a1, a2, ..., an (1 ≤ ai ≤ 109). Next m lines contain descriptions of queries, one per line. The j-th of these lines contains the description of the j-th query as two space-separated integers lj and rj (1 ≤ lj ≤ rj ≤ n).
Output
In m lines print m integers — the answers to the queries. The j-th line should contain the answer to the j-th query.
Examples
7 2
3 1 2 2 3 3 7
1 7
3 4
3
1
题意:
问区间内含有出现次数等于其值的数字个数
思路:
莫队。
没有什么值得解释的,只不过预处理离散化将时间由3790 ms优化到186 ms,必须写一个博客纪念一下。
1 #include<iostream> 2 #include<algorithm> 3 #include<vector> 4 #include<stack> 5 #include<queue> 6 #include<map> 7 #include<set> 8 #include<cstdio> 9 #include<cstring> 10 #include<cmath> 11 #include<ctime> 12 #define fuck(x) cout<<#x<<" = "<<x<<endl; 13 #define debug(a,i) cout<<#a<<"["<<i<<"] = "<<a[i]<<endl; 14 #define ls (t<<1) 15 #define rs ((t<<1)+1) 16 using namespace std; 17 typedef long long ll; 18 typedef unsigned long long ull; 19 const int maxn = 100086; 20 const int maxm = 100086; 21 const int inf = 2.1e9; 22 const ll Inf = 999999999999999999; 23 const int mod = 1000000007; 24 const double eps = 1e-6; 25 const double pi = acos(-1); 26 int num[maxn]; 27 struct node{ 28 int l,r; 29 int id; 30 }a[maxm]; 31 int anss[maxm]; 32 int block; 33 34 bool cmp(node a,node b){ 35 return (a.l/block!=b.l/block)?a.l<b.l:a.r<b.r; 36 } 37 int vis[100088]; 38 int rem[maxn],cnt; 39 int pos[maxn]; 40 int get_id(int x){ 41 return lower_bound(rem+1,rem+1+cnt,x)-rem; 42 } 43 44 int main() 45 { 46 int n; 47 scanf("%d",&n); 48 int m; 49 scanf("%d",&m); 50 for(int i=1;i<=n;i++){ 51 scanf("%d",&num[i]); 52 rem[i]=num[i]; 53 } 54 block=sqrt(n); 55 for(int i=1;i<=m;i++){ 56 scanf("%d%d",&a[i].l,&a[i].r); 57 a[i].id=i; 58 } 59 60 sort(a+1,a+1+m,cmp); 61 sort(rem+1,rem+1+n); 62 63 cnt=unique(rem+1,rem+1+n)-rem-1; 64 for(int i=1;i<=n;i++){ 65 pos[i]=get_id(num[i]); 66 } 67 int L=1,R=0; 68 int ans=0; 69 num[0]=-1; 70 for(int i=1;i<=m;i++){ 71 while(R<a[i].r){ 72 R++; 73 if(vis[pos[R]]==num[R]){ans--;} 74 vis[pos[R]]++; 75 if(vis[pos[R]]==num[R]){ans++;} 76 } 77 while(L<a[i].l){ 78 if(vis[pos[L]]==num[L]){ans--;} 79 vis[pos[L]]--; 80 if(vis[pos[L]]==num[L]){ans++;} 81 L++; 82 83 } 84 while(R>a[i].r){ 85 if(vis[pos[R]]==num[R]){ans--;} 86 vis[pos[R]]--; 87 if(vis[pos[R]]==num[R]){ans++;} 88 R--; 89 } 90 while(L>a[i].l){ 91 L--; 92 if(vis[pos[L]]==num[L]){ans--;} 93 vis[pos[L]]++; 94 if(vis[pos[L]]==num[L]){ans++;} 95 } 96 anss[a[i].id]=ans; 97 } 98 for(int i=1;i<=m;i++){ 99 printf("%d\n",anss[i]); 100 } 101 return 0; 102 }
如有侵权,联系删除
2290713181@qq.com