BZOJ 3339 && BZOJ 3585 莫队+权值分块

Posted on 2016-09-27 23:53  yyjxx2010xyu  阅读(161)  评论(0编辑  收藏  举报

 

显然若一个数大于n就不可能是答案。

 1  
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdio>
 5 #include <algorithm>
 6 #include <map>
 7 #include <cmath>
 8 using namespace std;
 9 const int Maxn=200010;
10 struct Info{int l,r,Id;}P[Maxn];
11 int a[Maxn],U[Maxn],Pos[Maxn],Belong[Maxn],Num[Maxn],L[Maxn],R[Maxn],Ans[Maxn];
12 int n,m,Block,tot;
13 inline bool cmp(Info A,Info B)
14 {
15     if (Pos[A.l]!=Pos[B.l]) return Pos[A.l]<Pos[B.l];
16     return A.r<B.r;
17 }
18 inline void Add(int x)
19 {
20     if (x>n) return;
21     if (U[x]==0) Num[Belong[x]]++;
22     U[x]++;
23 }
24 inline void Del(int x)
25 {
26     if (x>n) return;
27     U[x]--;
28     if (U[x]==0) Num[Belong[x]]--;
29 }
30 inline  int Query()
31 {
32     int i; for (i=1;i<=tot;i++) if (Num[i]!=Block) break;
33     for (int j=L[i];j<=R[i];j++)  if (!U[j]) return j;
34 }
35 int main()
36 {
37     scanf("%d%d",&n,&m); Block=(int)sqrt(n); tot=n/Block+1;
38     for (int i=0;i<=n;i++)
39     {
40         Belong[i]=i/Block+1;
41         if (!L[Belong[i]]) L[Belong[i]]=i;
42         R[Belong[i]]=i;
43     }L[1]=0;
44     for (int i=1;i<=n;i++) Pos[i]=i/Block+1;
45     for (int i=1;i<=n;i++) scanf("%d",&a[i]);
46     for (int i=1;i<=m;i++) scanf("%d%d",&P[i].l,&P[i].r),P[i].Id=i;
47     sort(P+1,P+m+1,cmp); int l=1,r=0;
48     for (int i=1;i<=m;i++)
49     {
50         while (r<P[i].r) Add(a[++r]);
51         while (l<P[i].l) Del(a[l++]);
52         while (l>P[i].l) Add(a[--l]);
53         while (r>P[i].r) Del(a[r--]);
54         Ans[P[i].Id]=Query();
55     }
56     for (int i=1;i<=m;i++) printf("%d\n",Ans[i]);
57     return 0;
58 }
C++