【SDOI2009】HH的项链 线段树
题目描述
HH 有一串由各种漂亮的贝壳组成的项链。HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义。HH 不断地收集新的贝壳,因此,他的项链变得越来越长。有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同的贝壳?这个问题很难回答……因为项链实在是太长了。于是,他只好求助睿智的你,来解决这个问题。
输入输出格式
输入格式:
第一行:一个整数N,表示项链的长度。
第二行:N 个整数,表示依次表示项链中贝壳的编号(编号为0 到1000000 之间的整数)。
第三行:一个整数M,表示HH 询问的个数。
接下来M 行:每行两个整数,L 和R(1 ≤ L ≤ R ≤ N),表示询问的区间。
输出格式:
M 行,每行一个整数,依次表示询问对应的答案。
输入输出样例
- 6
- 1 2 3 4 3 5
- 3
- 1 2
- 3 5
- 2 6
- 2
- 2
- 4
数据范围:
对于100%的数据,N <= 500000,M <= 500000。
---------------------------------------------------------------------------------------------------
这个数据一看就不能暴力标记什么的水过去
然后看到维护和询问的区间信息 所以很快想到了线段树
关键是维护的序列是什么呢?
我们选择维护一个1~n的序列 对每个点:为0表示此时下标表示的数不存在,为1表示此时下标表示的数存在
我们选择离线做法,先记录下每次询问 一边处理每个值 一边查询
将询问按照右端点排序,now记录当前访问到的询问
记last[i]数组 表示 i上一次出现的位置(即截止目前最后出现的位置
用一遍for循环 update贝壳的编号进入序列 即update(1,i,1); 表示现在在当前位出现
然后将上一次出现i的位置重置为0 即 update(1,last[a[i]],0); 并记下i出现的当前新位置last[a[i]]=i;
对于询问 每次从处理好的询问中 找出右端点和当前处理位置相同的询问 进行查询
怎样查询呢?
因为每一次我们只记录下了每个值最后出现的位置 以前的早已清零,所以查询一段区间中有多少的不同值就是做区间求和
于是就变成线段树的基本操作了ovo
注:1.注意线段树中查询操作的写法
2.注意开够数组
贴个代码
- #include<iostream>
- #include<cstdio>
- #include<algorithm>
- #include<cmath>
- #include<cstring>
- #define N 500100
- #define lc p<<1
- #define rc p<<1|1
- using namespace std;
- int n,m;
- int a[N];
- struct node
- {
- int l,r,val;
- }t[N<<];
- struct pu
- {
- int x,y,id,ans;
- }q[N];
- bool cmp(pu a,pu b) { return a.y<b.y; }
- bool cmp1(pu a,pu b) { return a.id<b.id; }
- void pushup(int p){
- t[p].val=t[lc].val+t[rc].val;
- }
- void build(int p,int l,int r)
- {
- t[p].l=l; t[p].r=r;
- if(l==r) return;
- int mid=l+r>>;
- build(lc,l,mid);
- build(rc,mid+,r);
- pushup(p);
- }
- void update(int p,int x,int v)
- {
- if(t[p].l==t[p].r)
- {
- t[p].val=v;
- return;
- }
- int mid=t[p].l+t[p].r>>;
- if(x<=mid) update(lc,x,v);
- else update(rc,x,v);
- pushup(p);
- }
- int query(int p,int ql,int qr)
- {
- //if(t[p].l<ql||t[p].r>qr) return 0;
- if(ql<=t[p].l&&t[p].r<=qr)
- return t[p].val;
- int ans=;
- int mid=t[p].l+t[p].r>>;
- if(ql<=mid) ans+=query(lc,ql,qr);
- if(qr>mid) ans+=query(rc,ql,qr);
- return ans;
- }
- int last[];
- int main()
- {
- scanf("%d",&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].x,&q[i].y);
- q[i].id=i;
- }
- build(,,n);
- int now=;
- sort(q+,q+m+,cmp);
- for(int i=;i<=n;i++)
- {
- update(,i,);
- if(last[a[i]]) update(,last[a[i]],);
- last[a[i]]=i;
- while(q[now].y==i)
- {
- q[now].ans=query(,q[now].x,q[now].y);
- now++;
- }
- }
- sort(q+,q+m+,cmp1);
- for(int i=;i<=m;i++)
- printf("%d\n",q[i].ans);
- return ;
- }
【SDOI2009】HH的项链 线段树的更多相关文章
- BZOJ 1878: [SDOI2009]HH的项链 离线树状数组
1878: [SDOI2009]HH的项链 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/p ...
- [bzoj1878][SDOI2009]HH的项链_树状数组
HH的项链 bzoj-1878 SDOI-2009 题目大意:给定一个n个数的序列,m次查询.查询区间数的种类个数. 注释:$1\le n \le 5\cdot 10^4$,$1\le m\le 2\ ...
- 【BZOJ】1878: [SDOI2009]HH的项链(树状数组)
http://www.lydsy.com/JudgeOnline/problem.php?id=1878 我太弱了,看题解才过的. 一开始看到此题,我想了想在线做法,但之后觉得这个想法可能是错的:维护 ...
- P1972 [SDOI2009]HH的项链[离线+树状数组/主席树/分块/模拟]
题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不断地收集新的贝壳,因此,他的项链 ...
- 洛谷P1972 [SDOI2009]HH的项链(树状数组)
题目链接: https://www.luogu.org/problemnew/show/P1972 题目描述: HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后 ...
- [BZOJ1878][SDOI2009] HH的项链 (树状数组)
link 一道简单题. 不用可持久化. 对于统计颜色个数,可以看与其颜色一样的前一个位置. 设$las(i)$表示其与$i$颜色相等的上一个位置. 则对于二元组$(l,r)$,其答案为$\sum_{i ...
- bzoj 1878: [SDOI2009]HH的项链【树状数组】
对于一个lr,每个颜色贡献的是在(1,r)区间里出现的最右位置,所以记录一个b数组表示当前点这个颜色上一个出现的位置 然后把询问离线,按r升序排序 每次把右端点右移,把这个点在树状数组上+1,并且在当 ...
- 洛谷 P1972 [SDOI2009]HH的项链(树状数组,离线)
传送门 解题思路 因为是求区间的不同种类数,所以我们用树状数组(貌似并没有什么直接联系) (...表示到) 还是和原来一样,用s[i]来表示a[i-lowbit(i)]...a[i]的种类数. 因为有 ...
- 洛谷——P1972 [SDOI2009]HH的项链(线段树)
P1972 [SDOI2009]HH的项链 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不断地收集新的 ...
随机推荐
- 新客户上云 - 来自 Azure 技术支持部门的忠告
本课程内容是来自 Azure 中国技术支持团队对新客户上云的忠告. 对于上云的新用户,Azure 技术支持部门有如下忠告: 1. 时刻关注并理解以下网站的变动来优化资源配置,更新设计方案. Azure ...
- VMware虚拟机配置文件(.vmx)损坏修复
我的虚拟机为VM14 装的ubuntu14.04server版 遇到ubuntu打不开,上网查阅了博客写的解决办法,尝试并解决了,以下分享个人心得: 首先进入虚拟机中系统安装的位置 查看日志文件 ...
- JS实现正则表达式
一.创建正则表达式 一共有两种方式: 1.直接量:var re = /[0-9]*/; 2.通过RegExp对象的构造函数:var re = RegExp("[0-9]*",&qu ...
- spring中用xml配置构造注入的心得
spring中用xml配置构造注入时,如果 <constructor-arg> 属性都是 ref ,则不用理会参数顺序 <constructor-arg ref="kill ...
- 部署JavaWeb时出现 If a file is locked,you can wait until
在部署JavaWeb程序时出现了if a file is locked ,you can wait until the lock stop的问题,这个主要是classpath目录出错或者jar包未导入 ...
- hihoCoder 挑战赛10 #1144 : 01串
思路:这只是逻辑测试题吧,考虑周全就行了.考虑n=m的情况,n>m的情况,m>n的情况. (1)n>m的情况,0比1多几个都是行的,一共有m个“01”,后面补足够多个零即可. (2) ...
- Web前端学习流程
- python剑指offer剪绳子
题目 给你一根长度为n的绳子,请把绳子剪成m段 (m和n都是整数,n>1并且m>1)每段绳子的长度记为k[0],k[1],…,k[m].请问k[0]k[1]…*k[m]可能的最大乘积是多少 ...
- C#做项目时的一些经验分享
1.对于公用的类型定义,要单独抽取出来,放到单独的DLL中. 2.通过大量定义interface接口,来提高模块化程度,不同功能之间通过实现接口来面向接口编程. 3.如果项目中存在很多非常相似,但是又 ...
- PAT (Basic Level) Practise (中文)- 1002. 写出这个数 (20)
http://www.patest.cn/contests/pat-b-practise/1002 读入一个自然数n,计算其各位数字之和,用汉语拼音写出和的每一位数字. 输入格式:每个测试输入包含1个 ...