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=1e6+5;//最大数字
 8 int unit,cnt[MAX],arr[N],res[N],ans=0;
 9
10 struct node{
11     int l,r,id;
12 }q[N];
13
14 bool cmp(node a,node b){
15     return a.l/unit!=b.l/unit?a.l/unit<b.l/unit:a.r<b.r;
16 }
17
18 void add(int pos){
19     cnt[arr[pos]]++;
20     if(cnt[arr[pos]]==1){
21         ans++;
22     }
23 }
24
25 void remove(int pos){
26     cnt[arr[pos]]--;
27     if(cnt[arr[pos]]==0){
28         ans--;
29     }
30 }
31
32 int main(){
33     int n;
34     scanf("%d",&n);
35     unit=sqrt(n);
36     for(int i=1;i<=n;i++){
37         scanf("%d",&arr[i]);
38     }
39     int m;
40     scanf("%d",&m);
41     for(int i=1;i<=m;i++){
42         scanf("%d%d",&q[i].l,&q[i].r);
43         q[i].id=i;
44     }
45
46     sort(q+1,q+m+1,cmp);
47
48     int L=q[1].l,R=L-1;
49     for(int i=1;i<=m;i++){
50         while(L>q[i].l)
51             add(--L);
52         while(L<q[i].l)
53             remove(L++);
54         while(R>q[i].r)
55             remove(R--);
56         while(R<q[i].r)
57             add(++R);
58         res[q[i].id]=ans;
59     }
60     for(int i=1;i<=m;i++){
61         printf("%d\n",res[i]);
62     }
63 }
时间: 2024-10-05 09:41:27

SPOJ D-query(莫队算法模板)的相关文章

Luogu 1494 - 小Z的袜子 - [莫队算法模板题][分块]

题目链接:https://www.luogu.org/problemnew/show/P1494 题目描述 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命-- 具体来说,小Z把这N只袜子从1到N编号,然后从编号L到R(L 尽管小Z并不在意两只袜子是不是完整的一双,甚至不在意两只袜子是否一左一右,他却很在意袜子的颜色,毕竟穿两只不同色的袜子会很尴尬. 你的任务便是告诉小Z,他有多大的概率抽到两只颜

莫队算法模板

形如hdu 5381:点击打开链接 add(int x, int y)的函数复杂度为 O(|x-y|) del同理 #pragma comment(linker, "/STACK:1024000000,1024000000") #include <stdio.h> #include <iostream> #include <algorithm> #include <sstream> #include <stdlib.h> #i

Luogu 1494 - 小Z的袜子 - [莫队算法模板题]

题目链接:https://www.luogu.org/problemnew/show/P1494 题目描述 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命-- 具体来说,小Z把这N只袜子从1到N编号,然后从编号L到R(L 尽管小Z并不在意两只袜子是不是完整的一双,甚至不在意两只袜子是否一左一右,他却很在意袜子的颜色,毕竟穿两只不同色的袜子会很尴尬. 你的任务便是告诉小Z,他有多大的概率抽到两只颜

BZOJ 2589 Spoj 10707 Count on a tree II 强制在线莫队算法(TLE)

题目大意:给定一棵树,每个节点有一个颜色,多次询问某条路径上颜色数量,强制在线 正解是块状数组,强制在线莫队会TLE到死,想AC这道题的不用看了 如果朴素的跑树上莫队其实并不难- - 但是强制在线 因此我们可以考虑强制在线莫队算法 将树分成O(n^1/3)块,每块大小O(n^2/3) 记录每两块之间的答案.每种颜色的出现次数和哪些点被记录到了答案中 每次查询先找到两端点所在块的端点的答案,然后暴力用莫队转移即可 空间复杂度O(n^1/3)*O(n^1/3)*O(n)=O(n^5/3) 预处理时间

莫队算法小结以及模板题

被splay折磨了一个星期还是抄模板都wa,调试的时候查数据都发现数据太大不能查的蒟蒻杨澜决定学习莫队算法, 但是 万万没想到 莫队也到处都是坑 ----------------------------------------------题记 莫队这个东西就是一个非常简♂单的类似动规的东西,也是那种不会就一直不会,一看题解秒懂的题,[虽然我看题解也半天看不懂但是只是第一道题,万事开头难嘛(也许吧)] 莫队算法是一种基于分块的离线算法,主要用来解决一些区间的询问[就是暴力],我们需要做的就是把询问

莫队算法小结(Markdown版)

wtf,最近挖坑有点小多啊,没办法>_<容我先把糖果公园A了再来写这个吧= =看看今天能不能A掉 好吧,我承认我第二天才把糖果公园A掉>_<下面把这篇小结补上 首先众所周知的是莫队算法是要把询问先按左端点属于的块排序,再按右端点排序 复杂度就先不证了,有兴趣的同学可以自己YY下或者查阅资料 下面举几个例子详细说明 1.小Z的袜子 Description: 给定一个序列m个询问 每次询问: 区间中选两个数,两个数相等的概率 若概率为0则输出01 仔细观察发现,令x表示x这个值出现的次

BZOJ 1878 [SDOI2009]HH的项链 (主席树 或 莫队算法)

题目链接  HH的项链 这道题可以直接上主席树的模板 #include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) #define dec(i, a, b) for (int i(a); i >= (b); --i) typedef long long LL; const int N = 5e4 + 10; const int M = 3e6 + 10

莫队算法小结

唔,想有更加舒爽的阅读体验请移步http://mlz000.logdown.com/posts/252433-mo-algorithm-summary 首先众所周知的是莫队算法是要把询问先按左端点属于的块排序,再按右端点排序 复杂度就先不证了,有兴趣的同学可以自己YY下或者查阅资料 下面举几个例子详细说明 1.小Z的袜子 Description: 给定一个序列m询问 每次询问: 区间中选两个数,两个数相等的概率 若概率为则输出0/1 仔细观察发现,令x表示x个值出现的次数,则每次询问[l,r]区

莫队算法

Beautiful Girl 题意 给定一个长度为 n 的序列 a[1], a[2], ..., a[n] . m 组询问 (l, r, K) , 求区间 [l, r] 去除重复的数之后的第 K 小. n, m <= 100000 . 分析 莫队算法 + 值域分块. 1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cctype> 5 #include &