先上一波题目 https://www.luogu.org/problem/P1972

这道题是询问区间内不同数的个数 明显不是正常的数据结构能够维护的

首先考虑 因为对于若干个询问的区间[l,r],如果他们的r都相等的话,那么项链中出现的同一个数字,一定是只关心出现在最右边的那一个的

例如项链:1 3 4 5 1

那么,对于r=5的所有的询问来说,第一个位置上的1完全没有意义,因为r已经在第五个1的右边,对于任何查询的[L,5]区间来说,如果第一个1被算了,那么他完全可以用第五个1来替代。

那么我们将询问按右端点从小到大进行排序 利用数据结构维护前缀和 涉及的操作有单点修改和区间(前缀和)查询

这样每次我们更新一个点的时候 就可以将和他同颜色的上一个点的影响消除 即将上一个点所在的位置-1 然后将当前点位置+1

这样问题就解决了qwq

然而这道题对线段树并不友好(可能我写的太丑了加上数据又加强了)T了一个点

经过各种玄学修改 比如将结构体换成数组 加上inline 甚至在读入优化的基础上 加上输出优化  还是T掉了qwq

但毕竟也算是正解 就挂一下好了

涉及的操作就是单点修改和区间求和了

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
const int M=1e6+;
int read(){
int ans=,f=,c=getchar();
while(c<''||c>''){if(c=='-') f=-; c=getchar();}
while(c>=''&&c<=''){ans=ans*+(c-''); c=getchar();}
return ans*f;
}
int n,m,s[M];
int last[M],ans[M];
struct node{int l,r,sum;}e[*M];
struct qwq{int id,l,r;}q[M];
int cmp(qwq x,qwq y){return x.r<y.r;}
void up(int x){e[x].sum=e[x<<].sum+e[x<<^].sum;}
void build(int x,int l,int r){
e[x].l=l; e[x].r=r;
if(l==r) return ;
int mid=l+r>>;
build(x<<,l,mid);
build(x<<^,mid+,r);
}
void del(int x,int D){
if(e[x].l==e[x].r&&e[x].l==D){
e[x].sum=;
return ;
}
int mid=e[x].l+e[x].r>>;
if(D<=mid) del(x<<,D);
if(D>mid) del(x<<^,D);
up(x);
}
void add(int x,int D){
if(e[x].l==e[x].r&&e[x].l==D){
e[x].sum=;
return ;
}
int mid=e[x].l+e[x].r>>;
if(D<=mid) add(x<<,D);
if(D>mid) add(x<<^,D);
up(x);
}
int p_ans(int x,int L,int R){
if(L>R) return ;
if(L<=e[x].l&&e[x].r<=R) return e[x].sum;
int ans=,mid=e[x].l+e[x].r>>;
if(L<=mid) ans+=p_ans(x<<,L,R);
if(R>mid) ans+=p_ans(x<<^,L,R);
return ans;
}
int main(){
n=read(); build(,,n);
for(int i=;i<=n;i++) s[i]=read();
m=read();
for(int i=;i<=m;i++) q[i].l=read(),q[i].r=read(),q[i].id=i;
sort(q+,q++m,cmp);
// for(int i=1;i<=m;i++) printf("qwq%d %d\n",q[i].l,q[i].r);
int x=;
for(int i=;i<=m;i++){
while(x<=q[i].r){
if(last[s[x]]) del(,last[s[x]]);
add(,x); last[s[x]]=x;
x++;
}
ans[q[i].id]=p_ans(,,q[i].r)-p_ans(,,q[i].l-);
// printf("qaq%d\n",x); }
for(int i=;i<=m;i++) printf("%d\n",ans[i]);
return ;
}

第二种做法自然就是树状数组了 树状数组的常数果然比线段树要小很多 跑得飞快

涉及的操作自然就是单点修改和求前缀和了

也算是复习了一波树状数组 这里挂一个大大的优秀讲解好了 https://www.cnblogs.com/xenny/p/9739600.html

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define lowbit(x) x&(-x)
using namespace std;
const int M=1e6+;
int read(){
int ans=,f=,c=getchar();
while(c<''||c>''){if(c=='-') f=-; c=getchar();}
while(c>=''&&c<=''){ans=ans*+(c-''); c=getchar();}
return ans*f;
}
int n,m,s[M],sum[M*];
int last[M],ans[M];
struct qwq{int id,l,r;}q[M];
int cmp(qwq x,qwq y){return x.r<y.r;}
void update(int x,int k){
while(x<=n){
sum[x]+=k;
x+=lowbit(x);
}
}
int p_ans(int x){
int ans=;
while(x){
ans+=sum[x];
x-=lowbit(x);
}
return ans;
}
int main(){
n=read();
for(int i=;i<=n;i++) s[i]=read();
m=read();
for(int i=;i<=m;i++) q[i].l=read(),q[i].r=read(),q[i].id=i;
sort(q+,q++m,cmp);
int x=;
for(int i=;i<=m;i++){
while(x<=q[i].r){
if(last[s[x]]) update(last[s[x]],-);
update(x,); last[s[x]]=x;
x++;
}
ans[q[i].id]=p_ans(q[i].r)-p_ans(q[i].l-);
}
for(int i=;i<=m;i++) printf("%d\n",ans[i]);
return ;
}

洛谷 P1972 [SDOI2009]HH的项链——树状数组的更多相关文章

  1. 【题解】P1972 [SDOI2009]HH的项链 - 树状数组

    P1972 [SDOI2009]HH的项链 声明:本博客所有题解都参照了网络资料或其他博客,仅为博主想加深理解而写,如有疑问欢迎与博主讨论✧。٩(ˊᗜˋ)و✧*。 题目描述 \(HH\) 有一串由各种 ...

  2. luogu 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的项链 解题报告

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

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

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

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

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

  8. 洛谷 P1972 [SDOI2009]HH的项链(树状数组,离线)

    传送门 解题思路 因为是求区间的不同种类数,所以我们用树状数组(貌似并没有什么直接联系) (...表示到) 还是和原来一样,用s[i]来表示a[i-lowbit(i)]...a[i]的种类数. 因为有 ...

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

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

随机推荐

  1. python面试题之如何读取大文件

    ① 利用生成器generator ②迭代器进行迭代遍历:for line in file 文章转载自Python黑洞网

  2. LayaBox 常用技巧

    1.修改IDE的菜单 找到安装路径的LayaAirIDE\resources\app\out\vs\layaEditor\renders\laya.editorUI.xml 注意事项: 1.mask的 ...

  3. C语言如何打印出%

    1. 敲ASCII码,但系我记不住呀! 2. 两个%%: #include <stdio.h> int main() { printf("%%\n"); printf( ...

  4. vue中监听返回键

    问题:在项目中,我们常常有需求,当用户在填写表单时,点击返回的时候,我们希望加一个弹窗,确认离开吗,确认将保存为草稿 解决方案:利用 H5的 pushstate(个人理解为增加页面栈)特性与onpop ...

  5. git stash--在不想commit的情况下进行git pull

    公司的git开发模式是“主干发布,分支开发”,大多数情况下是多个开发在同一dev分支上进行开发,因此需要经常pull代码,如果本地工作区存在代码修改,那么pull肯定失败,提示需要先commit已修改 ...

  6. 苹果推出了AI手机,打造一款高度个性化的设备

    在今年苹果的WWDC 2018上,一些人认为今年会因为软件专注而缺乏新的MacBook和iPad而感到无聊,该公司宣布,iOS12的推出可能是迄今为止最重要的操作系统更新.一系列Siri增强功能,Ap ...

  7. 6.jaxp的sax方式操作

    1.sax解析的原理 (1)解析xml有两种技术 dom 和 sax dom: 根据xml的层级结构在内存中分配一个树形结构,把xml中标签,属性,文本封装成对象 sax: 事件驱动,一行一行边读边解 ...

  8. 运行rabbitmq

    docker run -d -p 5672:5672 -p 15672:15672 --name myrabbitmq c4663bdca2cd

  9. abstractmethod

    a class with an abstract method cannot be instantiated (that is, we cannot create an instance by cal ...

  10. js this 指向

    JavaScript 作为一种脚本语言身份的存在,因此被很多人认为是简单易学的.然而情况恰恰相反,JavaScript 支持函数式编程.闭包.基于原型的继承等高级功能.由于其运行期绑定的特性,Java ...