【BZOJ 1878】 HH的项链
【题目链接】
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 ;
}
黄学长的代码(树状数组)
#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的项链的更多相关文章
- BZOJ 1878 hh的项链(简单莫队)
Description HH有一串由各种漂亮的贝壳组成的项链.HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一 段贝壳,思考它们所表达的含义.HH不断地收集新的贝壳,因此他的项链变得 ...
- BZOJ 1878 HH的项链(树状数组)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1878 题意:给出一个数列,每次询问区间[L,R]中有多少个不同的数字? 思路: (1)记 ...
- BZOJ 1878 HH的项链
不能分块(显然复杂度会炸啊.....) 离线+BIT.每个颜色在每个询问中只出现一次. #include<iostream> #include<cstdio> #include ...
- BZOJ 1878 HH的项链 | 主席树
题意 询问区间有多少不同的数. 题解 和Luogu 1903一样,这道题也是用pre数组来求区间不同数的个数,这里pre[i]表示a[i]上一次出现的位置 +1,询问相当于查询区间内有多少pre小于等 ...
- [bzoj] 1878 HH的项链 || 莫队
原题 给定长为 n 的一个序列,接下来 m 次询问,每次询问区间 [ l , r ] 内有多少个不同的数. 莫队: 离线\(O(n\log(n))\). 将序列分块. 以左端点所在块为第一关键字,右端 ...
- BZOJ 1878 HH的项链 (树状数组+离线)
题目大意:给你一个序列,求某区间出现不同的数的个数. 貌似离线树状数组是最好的解法 先把所有询问挂在它们询问的右端点上 然后从头到尾遍历这个序列,记录这个位置的值上一次出现的位置 那么,当遍历到第i位 ...
- Codevs 2307[SDOI2009]HH的项链
同题: Codevs 2307 HH的项链 BZOJ 1878 HH的项链 洛谷 1972 HH的项链 2009年省队选拔赛山东 时间限制: 1 s 空间限 ...
- 【BZOJ】【1878】【SDOI2009】HH的项链
树状数组/前缀和 Orz lct1999 好神的做法... 先看下暴力的做法:对于区间[l,r],我们依次扫过去,如果这个数是第一次出现,那么我们种类数+1. 我们发现:区间中相同的几个数,只有最左边 ...
- BZOJ 1878: [SDOI2009]HH的项链
1878: [SDOI2009]HH的项链 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 3548 Solved: 1757[Submit][Statu ...
- BZOJ 1878: [SDOI2009]HH的项链 离线树状数组
1878: [SDOI2009]HH的项链 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/p ...
随机推荐
- A - Boy or Girl(set)
Problem description Those days, many boys use beautiful girls' photos as avatars in forums. So it is ...
- 纯CSS3文字Loading动画特效
纯CSS3文字Loading动画特效是一款个性的loading文字加载动画. 在线演示本地下载
- Firebird Character Sets and Collations
Firebird Character Sets and Collations Every CHAR or VARCHAR field can (or, better: must) have a cha ...
- IIS网站调用FFMPEG执行截图命令失败的原因(暂时记录)
之前有个功能是用户上传视频后,网站对其进行截图处理.功能采用FFMPEG操作,在本机新建一个小程序进行调试时是没有问题的. 可功能原封不动挪到项目里,截图竟然失败了,于是开始排查. 期初以为是参数设置 ...
- 02--linux操作系统基础学习笔记
linux是一种操作系统. 嵌入式系统是以应用为中心的,以计算机技术为基础并且软硬件可剪裁,专用计算机系统. 内核下载网站 https://www.kernel.org/ https://www.ke ...
- JS 用+1、-1填12()34()56()78()9=59
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 解决value toDF is not a member of org.apache.spark.rdd.RDD (spark2.1 )
解决上述办法有两点: 1.两个import 需要放在 hiveCtx之后. val hiveCtx: SparkSession = SparkSession.builder.config(conf). ...
- Code VS 1002 搭桥
题目描述 Description 有一矩形区域的城市中建筑了若干建筑物,如果某两个单元格有一个点相联系,则它们属于同一座建筑物.现在想在这些建筑物之间搭建一些桥梁,其中桥梁只能沿着矩形的方格的边沿搭建 ...
- JAVA学习之枚举
1.新建一个枚举类 public enum Apple{ FUJI, PIPPIN, GRANNY_SMITH } 通过查看字节码,可以看到,枚举类的实现方式: 1)继承自java.lang.Enum ...
- 02.OOP面向对象-2.例子
class clothes: #初始化属性 def __init__(self,name,color): self.name = name self.color = color #转字符串 def _ ...