[SDOI2009][bzoj1878] HH的项链 [莫队模板题]

题面:

传送门

思路:

就是一道莫队的模板题目......

开一个1000000的数组记录每个数出现的次数,然后每次从1到0或者从0到1更新答案

莫队讲解看这里:莫队

Code:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 inline int read(){
 8     int re=0,flag=1;char ch=getchar();
 9     while(ch>‘9‘||ch<‘0‘){
10         if(ch==‘-‘) flag=-1;
11         ch=getchar();
12     }
13     while(ch>=‘0‘&&ch<=‘9‘) re=(re<<1)+(re<<3)+ch-‘0‘,ch=getchar();
14     return re*flag;
15 }
16 int n,m,cnt[1000010],tot=0,x[50010],curl,curr,block,ans[200010];
17 struct query{
18     int l,r,i;
19 }a[200010];
20 bool cmp(query l,query r){
21     if(l.l/block!=r.l/block) return (l.l/block)<(r.l/block);
22     else return l.r<r.r;
23 }
24 void add(int i){
25     cnt[x[i]]++;if(cnt[x[i]]==1) tot++;
26     //cout<<"add "<<i<<" "<<x[i]<<" "<<cnt[x[i]]<<"\n";
27 }
28 void erase(int i){
29     cnt[x[i]]--;if(!cnt[x[i]]) tot--;
30     //cout<<"erase "<<i<<" "<<x[i]<<" "<<cnt[x[i]]<<"\n";
31 }
32 int main(){
33     //freopen("diff.in","r",stdin);
34     //freopen("diff.out","w",stdout);
35     int i;
36     n=read();for(i=1;i<=n;i++) x[i]=read();block=sqrt(n);
37     //cout<<"input one complete "<<n<<" "<<i<<"\n";
38     m=read();for(i=1;i<=m;i++) a[i].l=read(),a[i].r=read(),a[i].i=i;
39     //cout<<"input two complete "<<m<<" "<<i<<"\n";
40     sort(a+1,a+m+1,cmp);curl=a[1].l;curr=a[1].r;
41     for(i=a[1].l;i<=a[1].r;i++) add(i);
42     ans[a[1].i]=tot;
43     for(i=2;i<=m;i++){
44         while(curl<a[i].l) erase(curl++);
45         while(curl>a[i].l) add(--curl);
46         while(curr<a[i].r) add(++curr);
47         while(curr>a[i].r) erase(curr--);
48         ans[a[i].i]=tot;
49         //cout<<"now "<<curl<<" "<<curr<<"\n";
50     }
51     for(i=1;i<=m;i++) printf("%d\n",ans[i]);
52 }
53 

原文地址:https://www.cnblogs.com/dedicatus545/p/8503746.html

时间: 2024-08-29 15:06:30

[SDOI2009][bzoj1878] HH的项链 [莫队模板题]的相关文章

BZOJ 1878: [SDOI2009]HH的项链 | 莫队

题解: http://www.lydsy.com/JudgeOnline/problem.php?id=1878 题解: 莫队板子题 核心思想是对区间的询问离线之后按照合理的顺序来优化复杂度 一般的做法是先分块,以左端点所在块为第一关键字,右端点位置为第二关键字排序 用两个指针来跑,这样可以证明的是时间复杂度为O(n√n) #include<cstdio> #include<algorithm> #include<cstring> #include<cmath&g

[BZOJ1878][SDOI2009]HH的项链 莫队

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1878 不带修改的莫队,用一个桶记录一下当前区间中每种颜色的数量就可以做到$O(1)$更新了. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 using namespace std; 6 int inline readint(){ 7 i

[bzoj] 1878 HH的项链 || 莫队

原题 给定长为 n 的一个序列,接下来 m 次询问,每次询问区间 [ l , r ] 内有多少个不同的数. 莫队: 离线\(O(n\log(n))\). 将序列分块. 以左端点所在块为第一关键字,右端点位置为第二关键字sort,然后two-points移动暴力记录即可. #include<cstdio> #include<algorithm> #include<cmath> #define N 50010 #define M 200010 using namespace

P1494 [国家集训队]小Z的袜子 莫队模板

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

SPOJ DQUERY D-query(莫队基础题)

题目链接:http://www.spoj.com/problems/DQUERY/ 题目: 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 subs

「SDOI2009」HH的项链

「SDOI2009」HH的项链 传送门 数据加强了,莫队跑不过了. 考虑用树状数组. 先把询问按右端点递增排序. 然后对于每一种贝壳,我们都用它最右一次出现的位置计算答案. 具体细节看代码吧. 参考代码: #include <algorithm> #include <cstdio> #define rg register #define file(x) freopen(x".in", "r", stdin), freopen(x".

数颜色(带修莫队模板)

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

【BZOJ】【1878】【SDOI2009】HH的项链

树状数组/前缀和 Orz lct1999 好神的做法... 先看下暴力的做法:对于区间[l,r],我们依次扫过去,如果这个数是第一次出现,那么我们种类数+1. 我们发现:区间中相同的几个数,只有最左边那个才对答案有贡献. 那么我们O(n)预处理一个next数组,满足a[i]=a[next[i]],且i~next[i]这一段中没有与a[i]相等的数....其实就是 i 右边第一个跟a[i]相等的值的下标啦.. 再回头看下我们的询问:对答案有贡献的数的特点是:它在整个序列中第一次出现,或者它是区间外

莫队模板

https://vjudge.net/problem/SPOJ-DQUERY 此题连接: 题目大意:给出一个n个数的序列: 接下来有k个询问,每一次询问某一区间里的不同数的个数: 莫队思想:分块 排序 暴力:先将所有询问存储起来,然后玄学排序降低复杂度: 1 #include<cstdio> 2 #include<algorithm> 3 #include<math.h> 4 #include<string.h> 5 #include<queue>