Description
Give you a sequence consisted of n numbers. You are required to answer how many pairs of numbers (ai, aj) satisfy that | ai - aj | = 1 and L ≤ i < j ≤ R.
Input
The input consists of one or more test cases.
For each case, the first line contains two numbers n and m, which represent the length of the number sequence and the number of queries. ( 1 ≤ n ≤ 10^4, 1 ≤ m ≤ 10^5 )
The second line consists of n numbers separated by n - 1 spaces.( 0 ≤ ai < 2^31 )
Then the m lines followed each contain two values Li and Ri.
Output
For each case just output the answers in m lines.
Sample Input
10 10
5 5 1 3 6 3 5 7 1 7
3 4
6 8
8 9
2 8
5 7
6 7
1 9
3 10
3 10
5 6
Sample Output
0 0 0 3 1 0 4 3 30
solution:
莫队算法模板题,只需要自己修稿O(1)的部分
#include<cstdio> #include<cmath> #include<algorithm> #include<map> using namespace std; const int maxn = 100050; int unit; int a[maxn]; int tmp, ans[maxn]; map<int, int>num; struct Query { int id, l, r; bool operator<(const Query &q)const { if (l / unit == q.l / unit) return r < q.r; return l / unit < q.l / unit; } }query[maxn]; void insert(int x) { ++num[x]; tmp += num[x + 1] + num[x - 1]; } void remove(int x) { --num[x]; tmp-= (num[x + 1]+num[x - 1]); } int main() { int n, m; while (~scanf("%d%d", &n, &m)) { for (int i = 1; i <= n; ++i) scanf("%d", &a[i]); unit = (int)sqrt((double)n); for (int i = 0; i < m; ++i) { query[i].id = i; scanf("%d%d", &query[i].l, &query[i].r); } sort(query, query + m); int l = 1, r = 0; tmp = 0; num.clear(); for (int i = 0; i<m; ++i) { while (l < query[i].l) remove(a[l++]); while (l > query[i].l) insert(a[--l]); while (r>query[i].r) remove(a[r--]); while (r < query[i].r) insert(a[++r]); ans[query[i].id] = tmp; } for (int i = 0; i <m; ++i) printf("%d\n", ans[i]); } return 0; }