D-query SPOJ - DQUERY(莫队)统计不同数的数量

A - D-query

Given a sequence of n numbers a1, a2, ..., an and a number of d-queries. A d-query is a pair (i, j) (1 ≤ i ≤ j ≤ n). For each d-query (i, j), you have to return the number of distinct elements in the subsequence ai, ai+1, ..., aj.

Input

  • Line 1: n (1 ≤ n ≤ 30000).
  • Line 2: n numbers a1, a2, ..., an (1 ≤ ai ≤ 106).
  • Line 3: q (1 ≤ q ≤ 200000), the number of d-queries.
  • In the next q lines, each line contains 2 numbers i, j representing a d-query (1 ≤ i ≤ j ≤ n).

Output

  • For each d-query (i, j), print the number of distinct elements in the subsequence ai, ai+1, ..., aj in a single line.

Example

Input
5
1 1 2 1 3
3
1 5
2 4
3 5

Output
3
2
3 解题思路:这道题就是给你n个数,q次查询,查询l到r区间有多少个不同的数字;此题用莫队算法;先贴代码,后期补充说明;代码如下:
 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 #include<cmath>
 5 using namespace std;
 6
 7 const int maxn = 200005;
 8 int n ;
 9 int m ;
10 int a[maxn];
11 int ans[maxn];
12 int vis[1000005];
13 int block[maxn];
14 int blocksize ;
15 int count1 = 0;
16 struct query{
17     int l ;
18     int r ;
19     int id ;
20 }q[maxn];
21 bool cmp(query a ,query b)
22 {
23     if(block[a.l]==block[b.l])
24         return a.r<b.r;
25     return block[a.l]<block[b.l];
26 }
27 void add(int num)
28 {
29     if(vis[a[num]]==0)
30         count1++;
31     vis[a[num]]++;
32 }
33 void remove(int num){
34     if(vis[a[num]]==1)
35         count1--;
36     vis[a[num]]--;
37 }
38 void solve()
39 {
40     int r = 0;
41     int l = 0;
42     for(int i = 0 ; i < m;i++)
43     {
44         while(q[i].r > r)
45         {
46             r++;
47             add(r);
48         }
49         while(q[i].r<r)
50         {
51             remove(r);
52             r--;
53         }
54         while(q[i].l>l)
55         {
56             remove(l);
57             l++;
58         }
59         while(q[i].l<l)
60         {
61             l--;
62             add(l);
63         }
64         ans[q[i].id] = count1;
65     }
66 }
67 int main()
68 {
69     scanf("%d",&n);
70     blocksize = sqrt(n);
71     for(int i = 1 ; i <= n ; i++)
72     {
73         scanf("%d",&a[i]);
74         block[i] = (i-1)/blocksize + 1;
75     }
76     scanf("%d",&m);
77     for(int i = 0; i < m;i++)
78     {
79         scanf("%d%d",&q[i].l,&q[i].r);
80         q[i].id = i;
81     }
82     sort(q,q+m,cmp);
83     solve();
84     for(int i = 0 ; i < m ;i++ )
85     {
86         printf("%d\n",ans[i]);
87     }
88     return 0;
89 }

原文地址:https://www.cnblogs.com/yewanting/p/10668201.html

时间: 2024-10-10 17:31:30

D-query SPOJ - DQUERY(莫队)统计不同数的数量的相关文章

SPOJ - DQUERY 莫队

题意:给定\(a[1...n]\),\(Q\)次询问,每次统计\([L,R]\)范围内有多少个不同的数字 xjb乱写就A了,莫队真好玩 #include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<string> #include<vector&g

SPOJ - FREQ2 莫队 / n^1.5logn爆炸

题意:给定\(a[1...n]\)和\(Q\)次询问,每次统计\([L,R]\)范围内出现频率最高的数的次数 想法没啥好说的,分别统计该数出现的次数和次数出现的次数,然后莫队暴力 注意本题时间卡的很紧,map无法通过 还有一个小细节是莫队时必须把add操作全部放在前面,保证操作不会数据越界,否则会RTE(调了一个上午..) 细节太重要了 #include<iostream> #include<algorithm> #include<cstdio> #include<

[莫队] 国家集训队 数颜色(尚未完成)

题目描述 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会向你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2. R P Col 把第P支画笔替换为颜色Col. 为了满足墨墨的要求,你知道你需要干什么了吗? 输入输出格式 输入格式: 第1行两个整数N,M,分别代表初始画笔的数量以及墨墨会做的事情的个数. 第2行N个整数,分别代表初始画笔排中第i支画笔的颜色. 第3行到第2+M行,每行分别代表墨墨会做的一件事

[带修莫队] Bzoj 2120 数颜色

Description 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2. R P Col 把第P支画笔替换为颜色Col.为了满足墨墨的要求,你知道你需要干什么了吗? Input 第1行两个整数N,M,分别代表初始画笔的数量以及墨墨会做的事情的个数.第2行N个整数,分别代表初始画笔排中第i支画笔的颜色.第3行到第2+M行,每行分别代表墨墨会做的一件事情,格

【带修莫队】bzoj2120 数颜色

块大小为n1/3. 把询问和修改分开. 每次两个询问之间的修改进行暴力转移,如果修改在上一次询问的区间里,就会对当前状态形成影响. 好慢. #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; #define N 10001 int num[N],n,m,b[N],a[N],enq,enc,anss[N]; struct ASK{

[BZOJ 4129]Haruna’s Breakfast(树上带修改莫队)

Description Haruna每天都会给提督做早餐! 这天她发现早饭的食材被调皮的 Shimakaze放到了一棵 树上,每个结点都有一样食材,Shimakaze要考验一下她. 每个食材都有一个美味度,Shimakaze会进行两种操作: 1.修改某个结点的食材的美味度. 2.对于某条链,询问这条链的美味度集合中,最小的未出现的自然数是多少.即mex值. 请你帮帮Haruna吧. Solution 树上带修改莫队 统计答案的时候也分块查询,找到第一个没满的块开始一个一个找 #include<i

4542: [Hnoi2016]大数|莫队

HN一天考两个莫队是什么鬼..或者说莫队不是正确的姿势..? 考虑已经知道了l..r的答案新添入r+1如何更新当前答案 需要先预处理出后缀modp的值bi,假设子序列l..r模p的值为x 那么x?10r?l+b[r]=b[l] 然后就可以直接莫队统计了 模数为2或5的时候要特判一下 #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cs

BZOJ 2120: 数颜色 带修改的莫队算法 树状数组套主席树

https://www.lydsy.com/JudgeOnline/problem.php?id=2120 标题里是两种不同的解法. 带修改的莫队和普通莫队比多了个修改操作,影响不大,但是注意一下细节不要出现zz错误. 这道题修改的数量比较少可以写莫队,但是如果修改数量多或者是特别极限的数据大概是不行的吧. 1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstrin

SPOJ D-query(莫队算法模板)

题目链接:http://www.spoj.com/problems/DQUERY/ 题目大意:给定一个数组,每次询问一个区间内的不同元素的个数 解题思路:直接套莫队的裸体 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cmath> 5 using namespace std; 6 const int N=3e5+5;//区间范围 7 const int MAX