[SDOI2009]HH的项链

题目背景

题目描述

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

输入输出格式

输入格式:

第一行:一个整数N,表示项链的长度。

第二行:N 个整数,表示依次表示项链中贝壳的编号(编号为0 到1000000 之间的整数)。

第三行:一个整数M,表示HH 询问的个数。

接下来M 行:每行两个整数,L 和R(1 ≤ L ≤ R ≤ N),表示询问的区间。

输出格式:

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

输入输出样例

输入样例#1:

6
1 2 3 4 3 5
3
1 2
3 5
2 6
输出样例#1:

2
2
4

说明

数据范围:

对于100%的数据,N <= 50000,M <= 200000。

——————————————————————我是分割线——————————————————————————

好题。

这题做法极多(e.g.树状数组、主席树等,甚至可以用各种诡异的做法来A)

但这里用莫队算法。

虽然原理早就懂了,但还是第一次写。(≧∀≦)ゞ好激动~

看到这题,第一时间想到莫队算法(毕竟是区间神器),但不知为何标签里没有(滑稽),于是自写一个。
题目大意:给n个数,m个询问,每个询问要求求出 l~r 之间出现了多少个不同的数字。

我们可以对区间进行分块以提高效率。根据分块算法的套路,以sqrt(n)为一个区间的长度。我们把询问以l为关键字从小到大排序,然后把l在当前区间的询问放在一组。然后呢,对于分到一组的询问,进行r为关键字从小到大的排序。然后进行暴力扫。

总复杂度为 O(m* sqrt(n)+sqrt(m)*n),还是可以接受的。

下面上代码:

 /*
Problem:[SDOI2009]HH的项链
OJ:洛谷
User:S.B.S.
Time:N/A
Memory:N/A
Length:N/A
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstdlib>
#include<iomanip>
#include<cassert>
#include<climits>
#include<functional>
#include<bitset>
#include<vector>
#include<list>
#define F(i,j,k) for(int i=j;i<=k;++i)
#define M(a,b) memset(a,b,sizeof(a))
#define FF(i,j,k) for(int i=j;i>=k;i--)
#define maxn 50001
#define inf 0x3f3f3f3f
#define maxm 200001
#define mod 998244353
//#define LOCAL
using namespace std;
int read(){
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,m;
int d[maxn];
struct QUERY
{
int l;
int r;
int data;
}q[maxm];
bool cmpl(QUERY a,QUERY b){return a.l<b.l;}
bool cmpr(QUERY a,QUERY b){if(a.r==b.r) return a.l<b.l;else return a.r<b.r;}
int ans[maxm],get[maxn];
int main()
{
std::ios::sync_with_stdio(false);//cout<<setiosflags(ios::fixed)<<setprecision(1)<<y;
#ifdef LOCAL
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
#endif
cin>>n;F(i,,n) cin>>d[i];cin>>m;
F(i,,m){cin>>q[i].l>>q[i].r;q[i].data=i;}
int len=sqrt(n);sort(q+,q+m+,cmpl);
int ll=,rr=,cnt=;
while(ll<=m)
{
rr++;int cur=ll;
while(q[ll].l<=rr*len&&ll<=m) ll++;
sort(q+cur,q+ll,cmpr);
if(rr==len) sort(q+cur,q+m+,cmpr);
}
ll=,rr=;
F(i,,m){
if(q[i].l>ll){
F(j,ll,q[i].l-){
get[d[j]]--;
if(get[d[j]]==) cnt--;
}
}
else{
F(j,q[i].l,ll-){
get[d[j]]++;
if(get[d[j]]==) cnt++;
}
}
ll=q[i].l;
if(q[i].r<rr){
F(j,q[i].r+,rr){
get[d[j]]--;
if(get[d[j]]==) cnt--;
}
}
else{
F(j,rr+,q[i].r){
get[d[j]]++;
if(get[d[j]]==) cnt++;
}
}
rr=q[i].r;
ans[q[i].data]=cnt;
}
F(i,,m) cout<<ans[i]<<endl;
return ;
}

p1972

洛谷P1972 [SDOI2009]HH的项链 题解的更多相关文章

  1. 洛谷 P1972 [SDOI2009]HH的项链【莫队算法学习】

    P1972 [SDOI2009]HH的项链 题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含 ...

  2. 洛谷 P1972 [SDOI2009]HH的项链 解题报告

    P1972 [SDOI2009]HH的项链 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不断 ...

  3. 洛谷——P1972 [SDOI2009]HH的项链(线段树)

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

  4. 洛谷 P1972 [SDOI2009]HH的项链-二维偏序+树状数组+读入挂(离线处理,思维,直接1~n一边插入一边查询),hahahahahahaha~

    P1972 [SDOI2009]HH的项链 题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含 ...

  5. [洛谷P1972][SDOI2009]HH的项链

    题目大意:给你一串数字,多次询问区间内数字的种类数 题解:莫队 卡点:洛谷数据加强,开了个$O(2)$ C++ Code: #include <cstdio> #include <a ...

  6. 洛谷P1972 [SDOI2009]HH的项链(树状数组)

    题目链接: https://www.luogu.org/problemnew/show/P1972 题目描述: HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后 ...

  7. 洛谷 P1972 [SDOI2009]HH的项链——树状数组

    先上一波题目 https://www.luogu.org/problem/P1972 这道题是询问区间内不同数的个数 明显不是正常的数据结构能够维护的 首先考虑 因为对于若干个询问的区间[l,r],如 ...

  8. 洛谷 P1972"[SDOI2009]HH的项链"(离线+树状数组 or 在线+主席树)

    传送门 •题意 给你一个包含 n 个数的数组 $a$: 有 m 此操作,每次操作求区间 [l,r] 中不同数的个数: •题解(离线+树状数组) 以样例 $[1,2,3,4,3,5]$ 为例,求解区间 ...

  9. 洛谷 P1972 [SDOI2009]HH的项链

    不是裸题,鉴定完毕. 我是题面 对于这道题,我是离线做的... 树状数组吧,好些点 我们可以很轻易地得到一个很显然的结论,就是关于同一个数,我们只需要记录它不超过当前区间的最后一次出现的位置即可.举例 ...

随机推荐

  1. 神仙数据结构——FHQ_Treap

    $FHQ\_Treap$是平衡树的一种,它不仅支持几乎所有的平衡树的操作,而且实现特别简单,总共只有两个操作.这里来简单介绍一下. 基本操作 $FHQ\_Treap$和$Treap$一样是需要用随机值 ...

  2. 转载-解决ORACLE 在控制台进行exp,导出时,空表不能导出

    一.问题原因: 11G中有个新特性,当表无数据时,不分配segment,以节省空间 1.insert一行,再rollback就产生segment了. 该方法是在在空表中插入数据,再删除,则产生segm ...

  3. 一个ScheduledExecutorService启动的Java线程无故挂掉引发的思考

    2018年12月12日18:44:53 一个ScheduledExecutorService启动的Java线程无故挂掉引发的思考 案件现场 不久前,在开发改造公司一个端到端监控日志系统的时候,出现了一 ...

  4. js加入购物车抛物线动画

    天猫将商品加入购物车会有一个抛物线动画,告诉用户操作成功以及购物车的位置,业务中需要用到类似的效果,记录一下实现过程备忘,先上demo 一开始没有想到用抛物线函数去做,也已经忘记还有这么个函数了,想着 ...

  5. strlen()和mb_strlen()

    换行需要用双引号,单引号只会输出字符. strlen()返回字符串所占的字节数,对于utf8编码的中文,一个汉字占三个字节. mb_strlen()返回字符个数,如果不写第二个参数,就会使用内部编码, ...

  6. TokenAutication源码分析

    创建的token如何交给前端进行使用呢? 在官方文档说明中,将产生的這个token放在header中 TokenAutication认证原理 用户认证成功以后,会在服务端产生一个Token.并且服务端 ...

  7. HDU 5835 Danganronpa 贪心

    Danganronpa 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5835 Description Chisa Yukizome works as ...

  8. Keil debugging techniques and alternative printf (SWO function)

    One of the basic needs of the embedded software development through the terminal to output debugging ...

  9. JVM菜鸟进阶高手之路

    http://www.jianshu.com/u/3def157aab07?utm_medium=note-author-link&utm_source=mobile

  10. socket recv阻塞与非阻塞error总结

    recv是socket编程中最常用的函数之一,在阻塞状态的recv有时候会返回不同的值,而对于错误值也有相应的错误码,分别对应不同的状态,下面是我针对常见的几种网络状态的简单总结. 首先阻塞接收的re ...