【题目链接】

https://www.lydsy.com/JudgeOnline/problem.php?id=1878

【算法】

显然,在线算法是不可做的,考虑离线算法

笔者的做法是莫队算法,时间复杂度 : O(nsqrt(n))(sqrt表示开方)

但是,树状数组的效率更高,下面讲一讲这种高效的做法 :

不妨将所有询问按右端点排序

对于每次询问,我们只考虑每种颜色最后出现的一次,用树状数组维护每一个位置是否对答案产生“贡献“

具体来说,我们用一个Next数组记录这种颜色上次出现的位置,然后,对于每个位置i,如果存在Next[i],将树状数组中的Next[i]减1,将这个位置加1即可

时间复杂度 :O(nlog(n))

【代码】

我的代码(莫队) :

#include<bits/stdc++.h>
using namespace std;
#define MAXN 50010
#define MAXS 1000010
#define MAXM 200010 struct Query
{
int l,r;
int id;
} q[MAXM],b[MAXM]; int i,j,k,n,m,block,len,t,sum,l,r;
int a[MAXN],s[MAXS],ans[MAXM]; inline bool cmp1(Query a,Query b)
{
return a.l < b.l;
}
inline bool cmp2(Query a,Query b)
{
return a.r < b.r;
}
inline void add(int l,int r,int val)
{
int i;
for (i = l; i <= r; i++)
{
if (s[a[i]] == && val == -) sum--;
if (s[a[i]] == && val == ) sum++;
s[a[i]] += val;
}
} int main()
{ scanf("%d",&n);
for (i = ; i <= n; i++) scanf("%d",&a[i]);
scanf("%d",&m);
for (i = ; i <= m; i++)
{
scanf("%d%d",&q[i].l,&q[i].r);
q[i].id = i;
}
sort(q+,q+m+,cmp1);
len = (int)sqrt(n);
block = n / len + (n % len != );
j = ;
for (i = ; i <= block; i++)
{
t = ;
sum = ;
while (j <= m && q[j].l > (i - ) * len && q[j].l <= i * len)
{
b[++t] = q[j];
j++;
}
sort(b+,b+t+,cmp2);
l = b[].l; r = b[].l - ;
for (k = ; k <= t; k++)
{
if (l < b[k].l) add(l,b[k].l-,-);
else if (l > b[k].l) add(b[k].l,l-,);
add(r+,b[k].r,);
ans[b[k].id] = sum;
l = b[k].l; r = b[k].r;
}
add(l,r,-);
}
for (i = ; i <= m; i++) printf("%d\n",ans[i]); return ;
}

黄学长的代码(树状数组)

(http://hzwer.com/3007.html)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
inline int read()
{
int x=;char ch=getchar();
while(ch<''||ch>''){ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x;
}
int n,m,mx;
int a[],next[],t[];
int p[];
struct data{int l,r,id,ans;}q[];
bool cmp1(data a,data b)
{return a.l==b.l?a.r<b.r:a.l<b.l;}
bool cmp2(data a,data b)
{return a.id<b.id;}
int lowbit(int x){return x&(-x);}
void update(int x,int v)
{
for(int i=x;i<=n;i+=lowbit(i))
t[i]+=v;
}
int ask(int x)
{
int tmp=;
for(int i=x;i>;i-=lowbit(i))
tmp+=t[i];
return tmp;
}
int main()
{
n=read();
for(int i=;i<=n;i++)
a[i]=read(),mx=max(mx,a[i]);
for(int i=n;i>;i--)
next[i]=p[a[i]],p[a[i]]=i;
for(int i=;i<=mx;i++)
if(p[i])update(p[i],);
m=read();
for(int i=;i<=m;i++)
q[i].l=read(),q[i].r=read(),q[i].id=i;
sort(q+,q+m+,cmp1);
int l=;
for(int i=;i<=m;i++)
{
while(l<q[i].l)
{
if(next[l])update(next[l],);
l++;
}
q[i].ans=ask(q[i].r)-ask(q[i].l-);
}
sort(q+,q+m+,cmp2);
for(int i=;i<=m;i++)
printf("%d\n",q[i].ans);
return ;
}

【BZOJ 1878】 HH的项链的更多相关文章

  1. BZOJ 1878 hh的项链(简单莫队)

    Description HH有一串由各种漂亮的贝壳组成的项链.HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一 段贝壳,思考它们所表达的含义.HH不断地收集新的贝壳,因此他的项链变得 ...

  2. BZOJ 1878 HH的项链(树状数组)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1878 题意:给出一个数列,每次询问区间[L,R]中有多少个不同的数字? 思路: (1)记 ...

  3. BZOJ 1878 HH的项链

    不能分块(显然复杂度会炸啊.....) 离线+BIT.每个颜色在每个询问中只出现一次. #include<iostream> #include<cstdio> #include ...

  4. BZOJ 1878 HH的项链 | 主席树

    题意 询问区间有多少不同的数. 题解 和Luogu 1903一样,这道题也是用pre数组来求区间不同数的个数,这里pre[i]表示a[i]上一次出现的位置 +1,询问相当于查询区间内有多少pre小于等 ...

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

    原题 给定长为 n 的一个序列,接下来 m 次询问,每次询问区间 [ l , r ] 内有多少个不同的数. 莫队: 离线\(O(n\log(n))\). 将序列分块. 以左端点所在块为第一关键字,右端 ...

  6. BZOJ 1878 HH的项链 (树状数组+离线)

    题目大意:给你一个序列,求某区间出现不同的数的个数. 貌似离线树状数组是最好的解法 先把所有询问挂在它们询问的右端点上 然后从头到尾遍历这个序列,记录这个位置的值上一次出现的位置 那么,当遍历到第i位 ...

  7. Codevs 2307[SDOI2009]HH的项链

    同题:     Codevs 2307 HH的项链     BZOJ    1878 HH的项链     洛谷      1972 HH的项链 2009年省队选拔赛山东  时间限制: 1 s  空间限 ...

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

    树状数组/前缀和 Orz lct1999 好神的做法... 先看下暴力的做法:对于区间[l,r],我们依次扫过去,如果这个数是第一次出现,那么我们种类数+1. 我们发现:区间中相同的几个数,只有最左边 ...

  9. BZOJ 1878: [SDOI2009]HH的项链

    1878: [SDOI2009]HH的项链 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 3548  Solved: 1757[Submit][Statu ...

  10. BZOJ 1878: [SDOI2009]HH的项链 离线树状数组

    1878: [SDOI2009]HH的项链 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/p ...

随机推荐

  1. A - Boy or Girl(set)

    Problem description Those days, many boys use beautiful girls' photos as avatars in forums. So it is ...

  2. 纯CSS3文字Loading动画特效

    纯CSS3文字Loading动画特效是一款个性的loading文字加载动画. 在线演示本地下载

  3. Firebird Character Sets and Collations

    Firebird Character Sets and Collations Every CHAR or VARCHAR field can (or, better: must) have a cha ...

  4. IIS网站调用FFMPEG执行截图命令失败的原因(暂时记录)

    之前有个功能是用户上传视频后,网站对其进行截图处理.功能采用FFMPEG操作,在本机新建一个小程序进行调试时是没有问题的. 可功能原封不动挪到项目里,截图竟然失败了,于是开始排查. 期初以为是参数设置 ...

  5. 02--linux操作系统基础学习笔记

    linux是一种操作系统. 嵌入式系统是以应用为中心的,以计算机技术为基础并且软硬件可剪裁,专用计算机系统. 内核下载网站 https://www.kernel.org/ https://www.ke ...

  6. JS 用+1、-1填12()34()56()78()9=59

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. 解决value toDF is not a member of org.apache.spark.rdd.RDD (spark2.1 )

    解决上述办法有两点: 1.两个import 需要放在 hiveCtx之后. val hiveCtx: SparkSession = SparkSession.builder.config(conf). ...

  8. Code VS 1002 搭桥

    题目描述 Description 有一矩形区域的城市中建筑了若干建筑物,如果某两个单元格有一个点相联系,则它们属于同一座建筑物.现在想在这些建筑物之间搭建一些桥梁,其中桥梁只能沿着矩形的方格的边沿搭建 ...

  9. JAVA学习之枚举

    1.新建一个枚举类 public enum Apple{ FUJI, PIPPIN, GRANNY_SMITH } 通过查看字节码,可以看到,枚举类的实现方式: 1)继承自java.lang.Enum ...

  10. 02.OOP面向对象-2.例子

    class clothes: #初始化属性 def __init__(self,name,color): self.name = name self.color = color #转字符串 def _ ...