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\n",res[i]);
79         }
80     }
81     return 0;
82 }
时间: 2024-10-13 12:29:47

HDU 4638 (莫队)的相关文章

HDU 4638 莫队算法

Group Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2483    Accepted Submission(s): 1272 Problem Description There are n men ,every man has an ID(1..n).their ID is unique. Whose ID is i and i-

HDU 6333 莫队+组合数

Problem B. Harvest of Apples Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 2397    Accepted Submission(s): 934 Problem Description There are n apples on a tree, numbered from 1 to n.Count th

HDU 5145 NPY and girls (莫队分块离线)

题目地址:HDU 5145 莫队真的好神奇..这样的复杂度居然只有n*sqrt(n)... 裸的莫队分块,先离线,然后按左端点分块,按块数作为第一关键字排序,然后按r值作为第二关键字进行排序.都是从小到大,可以证明这样的复杂度只有n*sqrt(n).然后进行块之间的转移. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <

HDU 4638 Group (莫队算法||线段树离散查询)

题目地址:HDU 4638 先写了一发莫队,莫队可以水过.很简单的莫队,不多说. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #include <set> #include <s

hdu 4638 Group 莫队算法

题目链接 很裸的莫队, 就不多说了... 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define pb(x) push_back(x) 4 #define ll long long 5 #define mk(x, y) make_pair(x, y) 6 #define lson l, m, rt<<1 7 #define mem(a) memset(a, 0, sizeof(a)) 8 #define rson m+1

hdu 4638 Group(莫队算法|离线线段树)

Group Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1323    Accepted Submission(s): 703 Problem Description There are n men ,every man has an ID(1..n).their ID is unique. Whose ID is i and i-

hdu NPY and girls 莫队+逆元

NPY and girls Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description NPY's girlfriend blew him out!His honey doesn't love him any more!However, he has so many girlfriend candidates.Because there are to

hdu 5381 The sum of gcd 莫队+预处理

The sum of gcd Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Problem Description You have an array A,the length of A is nLet f(l,r)=∑ri=l∑rj=igcd(ai,ai+1....aj) Input There are multiple test cases. The first line

HDU 5145 NPY and girls(莫队算法+乘法逆元)

[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5145 [题目大意] 给出一个数列,每次求一个区间数字的非重排列数量.答案对1e9+7取模. [题解] 我们发现每次往里加入一个新的数字或者减去一个新的数字,前后的排列数目是可以通过乘除转移的,所以自然想到用莫队算法处理.因为答案要求取模,所以在用除法的时候要计算逆元. [代码] #include <cstdio> #include <algorithm> #include <