HDU 4638 (莫队)

题目链接:Problem - 4638

做了两天莫队和分块,留个模板吧。

当插入r的时候,设arr[r]代表r的位置的数字,判断vis[arr[r-1]]和vis[arr[r+1]]是否访问过,如果两个都访问过,那么块的个数-1,如果有一个访问过,块的个数不变,如果都为0,块的个数+1.

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <cmath>
 6 using namespace std;
 7 const int maxn = 1e5+50;
 8 int vis[maxn];
 9 struct node
10 {
11     int l,r;
12     int block;
13     int id;
14 };
15 node q[maxn];
16 int arr[maxn];
17 bool cmp(node A,node B)
18 {
19     if(A.block==B.block) return A.r<B.r;
20     return A.l<B.l;
21 }
22 int res[maxn];
23 int query(int l,int r)
24 {
25     if(vis[l]==1&&vis[r]==1) return -1;
26     if((vis[l]==1&&vis[r]==0)||(vis[l]==0&&vis[r]==1)) return 0;
27     if(vis[l]==0&&vis[r]==0) return 1;
28 }
29 int main()
30 {
31     int T;cin>>T;
32     while(T--)
33     {
34         int n,m;
35         scanf("%d %d",&n,&m);
36         int block = sqrt(n);
37         for(int i=1;i<=n;i++) scanf("%d",&arr[i]);
38         memset(vis,0,sizeof(vis));
39         for(int i=1;i<=m;i++)
40         {
41             scanf("%d %d",&q[i].l,&q[i].r);
42             q[i].block = q[i].l/block;
43             q[i].id = i;
44         }
45         sort(q+1,q+m+1,cmp);
46         int l=1,r=0;
47         int ans = 0;
48         for(int i=1;i<=m;i++)
49         {
50             while(r < q[i].r)
51             {
52                 r++;
53                 vis[arr[r]] = 1;
54                 ans += query(arr[r]-1,arr[r]+1);
55             }
56             while(r > q[i].r)
57             {
58                 ans -= query(arr[r]-1,arr[r]+1);
59                 vis[arr[r]] = 0;
60                 r--;
61             }
62             while(l < q[i].l)
63             {
64                 ans -= query(arr[l]-1,arr[l]+1);
65                 vis[arr[l]] = 0;
66                 l++;
67             }
68             while(l > q[i].l)
69             {
70                 l--;
71                 vis[arr[l]] = 1;
72                 ans += query(arr[l]-1,arr[l]+1);
73             }
74             res[q[i].id] = ans;
75         }
76         for(int i=1;i<=m;i++)
77         {
78             printf("%d
",res[i]);
79         }
80     }
81     return 0;
82 }
原文地址:https://www.cnblogs.com/littlepear/p/5768605.html