Description

HH有一串由各种漂亮的贝壳组成的项链。HH相信不同的贝 壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义。HH不断地收集新的贝壳,因此,他的项链变得越来越长。有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同 的贝壳?这个问题很难回答。。。因为项链实在是太长了。于是,他只好求助睿智的你,来解决这个问题。

Input

第一行:一个整数N,表示项链的长度。 第二行:N个整数,表示依次表示项链中贝壳的编号(编号为0到1000000之间的整数)。 第三行:一个整数M,表示HH询问的个数。 接下来M行:每行两个整数,L和R(1 ≤ L ≤ R ≤ N),表示询问的区间。

Output

M行,每行一个整数,依次表示询问对应的答案。

Sample Input

6
1 2 3 4 3 5
3
1 2
3 5
2 6

Sample Output

2
2
4

HINT

对于20%的数据,N ≤ 100,M ≤ 1000;
对于40%的数据,N ≤ 3000,M ≤ 200000;
对于100%的数据,N ≤ 50000,M ≤ 200000。

题解

这题首先在线是没法做的,所以我们可以考虑离线算法

解法1:莫队裸题,分块就好。

 #include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<cstdio>
#include<string>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
#define RE register
#define IL inline
using namespace std;
const int M=;
const int N=;
const int Q=; int cnt[M+],ans;
int keep[Q+];
int n,m,a[N+],tim;
struct query
{
int l,r,id;
}q[Q+];
bool comp(const query &a,const query &b){return a.l/tim==b.l/tim ? a.r<b.r:a.l<b.l;} int main()
{
scanf("%d",&n);
tim=sqrt(n);
for (int i=;i<=n;i++) scanf("%d",&a[i]);
scanf("%d",&m);
for (int i=;i<=m;i++)
{
scanf("%d%d",&q[i].l,&q[i].r);
q[i].id=i;
}
sort(q+,q+m+,comp);
int curl=,curr=,l,r;
for (int i=;i<=m;i++)
{
l=q[i].l,r=q[i].r;
while (curl<l) {cnt[a[curl]]--;ans-=(cnt[a[curl++]]==);}
while (curl>l) {cnt[a[--curl]]++;ans+=(cnt[a[curl]]==);}
while (curr<r) {cnt[a[++curr]]++;ans+=(cnt[a[curr]]==);}
while (curr>r) {cnt[a[curr]]--;ans-=(cnt[a[curr--]]==);}
keep[q[i].id]=ans;
}
for (int i=;i<=m;i++) printf("%d\n",keep[i]);
return ;
}

莫队

解法2:排序+树状数组。

首先记录下每种颜色的下一种颜色所在的位置,将所有询问按照右端点进行排序。

左往右扫,扫过一个元素将该位置++,若有前驱,将前驱--。

扫到区间端点,答案为$sum[r]-sum[l-1]$,记录一下就好。(其中$sum$为前缀和)

前缀和用树状数组实现。

 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
struct Node
{
int l,r,num;
}s[];
int a[],ans[],n,m,c[],vis[];
bool cmp(Node a,Node b)
{
return (a.r<b.r||(a.r==b.r&&a.l<b.l));
}
int getsum(int x)
{
int s=;
while (x)
{
s+=c[x];
x-=(x&(-x));
}
return s;
}
void add(int x,int d)
{
while (x<=n)
{
c[x]+=d;
x+=(x&(-x));
}
}
int main()
{int i,j;
cin>>n;
for (i=;i<=n;i++)
{
scanf("%d",&a[i]);
}
cin>>m;
for (i=;i<=m;i++)
{
scanf("%d%d",&s[i].l,&s[i].r);
s[i].num=i;
}
sort(s+,s+m+,cmp);
j=;
for (i=;i<=n+;i++)
{
while (j<=m&&i>s[j].r)
{
ans[s[j].num]=getsum(s[j].r)-getsum(s[j].l-);
j++;
}
if (i>n) break;
if (vis[a[i]])
{
add(vis[a[i]],-);
vis[a[i]]=i;
add(i,);
}
else
{
vis[a[i]]=i;
add(i,);
}
}
for (i=;i<=m;i++)
printf("%d\n",ans[i]);
}

排序+树状数组

[SDOI 2009]HH的项链的更多相关文章

  1. [ SDOI 2009 ] HH的项链 & [ HEOI 2012 ] 采花

    \(\\\) \(Description\) 给出一个长为\(N\)的序列,\(M\)次询问区间\([L_i,R_i]\)内不同数字的个数. \(N\in [1,5\times 10^4]\),\(M ...

  2. BZOJ 1878 SDOI 2009 HH项链 树状数组 + 脱机处理

    标题效果:一些珠子项链.珠具有不同的颜色.我们问了很多次有多少种不同的颜色有过一段范围. 思考:这个问题让我学会聪明的离线实践.按左端点排序问题.加工出来的位置每种颜色首次出现.每一种颜色的下一次出现 ...

  3. [SDOI 2009]HH去散步

    Description HH有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但 是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回. 又 ...

  4. [BZOJ 1875] [SDOI 2009] HH去散步【矩阵乘法】

    题目链接:BZOJ - 1875 题目分析: 这道题如果去掉“不会立刻沿着刚刚走来的路走回”的限制,直接用邻接矩阵跑矩阵乘法就可以了.然而现在加了这个限制,建图的方式就要做一些改变.如果我们把每一条边 ...

  5. sdoi 2009 HH去散步 矩阵乘

    如果没有题里的"不会立刻沿着刚刚走来的路走回"限制,那么直接矩乘计算k步的方案数 但加了这个限制,就不能以点来矩乘了,考虑边数<=60,如果以边建邻接矩阵呢?? 先拆边,再把 ...

  6. Codevs 2307[SDOI2009]HH的项链

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

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

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

  8. BZOJ-1878 HH的项链 树状数组+莫队(离线处理)

    1878: [SDOI2009]HH的项链 Time Limit: 4 Sec Memory Limit: 64 MB Submit: 2701 Solved: 1355 [Submit][Statu ...

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

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

随机推荐

  1. Beta阶段敏捷冲刺报告-DAY4

    Beta阶段敏捷冲刺报告-DAY4 Scrum Meeting 敏捷开发日期 2017.11.5 会议时间 11:30 会议地点 羽毛球场 参会人员 全体成员 会议内容 bug的原因讨论, 测试内容安 ...

  2. Flask 学习 十四 测试

    获取代码覆盖报告 安装代码覆盖工具 pip install coverage manage.py 覆盖检测 COV = None if os.environ.get('FLASK_COVERAGE') ...

  3. bzoj千题计划275:bzoj4817: [Sdoi2017]树点涂色

    http://www.lydsy.com/JudgeOnline/problem.php?id=4817 lct+线段树+dfs序 操作1:access 操作2:u到根的-v到根的-lca到根的*2+ ...

  4. WPF自学入门(十一)WPF MVVM模式Command命令

    在WPF自学入门(十)WPF MVVM简单介绍中的示例似乎运行起来没有什么问题,也可以进行更新.但是这并不是我们使用MVVM的正确方式.正如上一篇文章中在开始说的,MVVM的目的是为了最大限度地降低了 ...

  5. node框架koa

    node的两大常见web服务器框架有express和koa,之前已经介绍过express了现在来介绍下koa吧~ koa也是express团队的出品,意在利用es7新出的async来告别"回 ...

  6. Angular 学习笔记 ( CDK - Overlays )

    更新 : 2018-01-30 ng 的 overlap 在关闭的时候对 backdrop 做了一个 style pointer 目的是让 backdrop 不被 2 次点击, 但是呢,  css p ...

  7. Docker学习笔记 - Docker的数据卷

    一.什么是数据卷? 数据卷是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性: 数据卷可以在容器之间共享和重用 对数据卷的修改会立马生效 对数据卷的更新,不会影响镜像 数据 ...

  8. 在ABPZERO中,扩展实体的方法。

    内容 介绍 扩展的抽象实体 将新属性添加给用户 添加迁移 在界面上显示地址 在用户编辑/添加功能中添加地址 扩展的非抽象类实体 获得版本的派生实体 添加迁移 在界面上添加价格 在创建/编辑版本功能中加 ...

  9. Spring 4.2.5 + Quartz 2.2.0整合

    jar包使用的Maven库管理的,在这就不罗列了,注意下只有spring3.x以上的版本才支持quartz2.x的版本. 配置文件: <?xml version="1.0" ...

  10. python中文编码坑

    打印list的时候unicode对象不会自动转为中文!