先上一波题目 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. Pandas的拼接操作

    pandas的拼接操作 pandas的拼接分为两种: 级联:pd.concat, pd.append 合并:pd.merge, pd.join import pandas as pd import n ...

  2. 观list.clear()方法 有感

    一 . list.clear()底层源码实现 在使用list 结合的时候习惯了 list=null :在创建这样的方式,但是发现使用list的clear 方法很不错,尤其是有大量循环的时候 1.lis ...

  3. 实例之跑马灯,函数创建、通过ID获取标签及内部的值,字符串的获取与拼接、定时器的使用

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. HTML5中canvas与SVG有什么区别

    SVG SVG 是一种使用 XML 描述 2D 图形的语言,它基于XML也就是我们可以为某个元素附加JavaScript事件处理器,如果SVG 对象的属性发生变化,那么浏览器能够自动重现图形. Can ...

  5. 安卓构架组件——向项目添加组件(Adding Components to your Project)

    在开始之前,建议阅读 应用架构指南. Before getting started, we recommend reading the Architecture Components Guide to ...

  6. Mac版Navicat Premium激活教程

    工具: Navicat Premium12.0.20 安装包 下载注册机工具包 链接:https://pan.baidu.com/s/1NS8gk780ds1Xn-zHrSIzIw  密码:dvke ...

  7. I2C走线技巧

  8. neuoj Blurred Pictures(小思维题

    https://oj.neu.edu.cn/problem/1505 题意:一张由n*n的照片,每行从第ai个像素点到第bi个像素点是非模糊点,要求找出最大的正方形,该正方形中的像素都是非模糊点. 思 ...

  9. Makefile中几种变量赋值运算符

    Makefile中几种变量赋值运算符: =      :最简单的赋值 :=     :一般也是赋值 以上这两个大部分情况下效果是一样的,但是有时候不一样. 用 = 赋值的变量,在被解析时他的值取决于最 ...

  10. ltp-ddt smp_cpu_affinity

    # @name SMP CPU Affinity# @desc Check that processes assigned to multiple CPUs complete without erro ...