HH的项链(树状数组)区间内不同的数量

2023-12-28 07:38

本文主要是介绍HH的项链(树状数组)区间内不同的数量,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

HH有一串由各种漂亮的贝壳组成的项链。HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一
段贝壳,思考它们所表达的含义。HH不断地收集新的贝壳,因此他的项链变得越来越长。有一天,他突然提出了一
个问题:某一段贝壳中,包含了多少种不同的贝壳?这个问题很难回答。。。因为项链实在是太长了。于是,他只
好求助睿智的你,来解决这个问题。
Input
第一行:一个整数N,表示项链的长度。 
第二行:N个整数,表示依次表示项链中贝壳的编号(编号为0到1000000之间的整数)。 
第三行:一个整数M,表示HH询问的个数。 
接下来M行:每行两个整数,L和R(1 ≤ L ≤ R ≤ N),表示询问的区间。
N ≤ 50000,M ≤ 200000。
Output

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

Sample Input
6
1 2 3 4 3 5
3
1 2 
3 5
2 6
Sample Output
2
2
4
Hint


题意:

有一串项链,每点有个颜色,给你个区间。查询这个区间内有几种不同的颜色?

思路:

预处理出上一个与i颜色相同的点pre[i],将询问按右端点排序,然后一边往树状数组进入点一边处理询,注意其中一些小技巧。

代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int n,m,sum;
const int maxn=1000010;
int pre[maxn],s[maxn],p[maxn],head[maxn],ans[maxn];
struct Q
{int l,r,id;
}q[maxn];
bool cmp(Q a,Q b)
{return a.r<b.r;
}
int lowbit(int i){return i&-i;
}
void updata(int x,int v)   //单点更新
{if(!x)  return ;sum+=v;                //记录的更新的次数//  cout<<sum<<"......"<<endl;while(x<=n){s[x]+=v;x+=lowbit(x);
}}
int query(int x) //查询0-x和
{int i,res=0;while(x>0){res+=s[x];x-=lowbit(x);
}return res;
}
int main()
{scanf("%d",&n);int i,j;for(i=1;i<=n;i++){scanf("%d",&p[i]);pre[i]=head[p[i]];  //仔细理解head[p[i]]=i;}scanf("%d",&m);for(i=1;i<=m;i++)    scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i;sort(q+1,q+m+1,cmp);for(i=j=1;i<=m;i++){for(;j<=q[i].r;j++) updata(pre[j],-1),updata(j,1);  //核心处ans[q[i].id]=sum-query(q[i].l-1);}for(i=1;i<=m;i++)    printf("%d\n",ans[i]);return 0;
}

多看 多学 多想

这篇关于HH的项链(树状数组)区间内不同的数量的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/545349

相关文章

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2

vue如何监听对象或者数组某个属性的变化详解

《vue如何监听对象或者数组某个属性的变化详解》这篇文章主要给大家介绍了关于vue如何监听对象或者数组某个属性的变化,在Vue.js中可以通过watch监听属性变化并动态修改其他属性的值,watch通... 目录前言用watch监听深度监听使用计算属性watch和计算属性的区别在vue 3中使用watchE

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

2. c#从不同cs的文件调用函数

1.文件目录如下: 2. Program.cs文件的主函数如下 using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using System.Windows.Forms;namespace datasAnalysis{internal static

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

uva 10061 How many zero's and how many digits ?(不同进制阶乘末尾几个0)+poj 1401

题意是求在base进制下的 n!的结果有几位数,末尾有几个0。 想起刚开始的时候做的一道10进制下的n阶乘末尾有几个零,以及之前有做过的一道n阶乘的位数。 当时都是在10进制下的。 10进制下的做法是: 1. n阶位数:直接 lg(n!)就是得数的位数。 2. n阶末尾0的个数:由于2 * 5 将会在得数中以0的形式存在,所以计算2或者计算5,由于因子中出现5必然出现2,所以直接一

hdu 1754 I Hate It(线段树,单点更新,区间最值)

题意是求一个线段中的最大数。 线段树的模板题,试用了一下交大的模板。效率有点略低。 代码: #include <stdio.h>#include <string.h>#define TREE_SIZE (1 << (20))//const int TREE_SIZE = 200000 + 10;int max(int a, int b){return a > b ? a :

hdu 1166 敌兵布阵(树状数组 or 线段树)

题意是求一个线段的和,在线段上可以进行加减的修改。 树状数组的模板题。 代码: #include <stdio.h>#include <string.h>const int maxn = 50000 + 1;int c[maxn];int n;int lowbit(int x){return x & -x;}void add(int x, int num){while

hdu4267区间统计

题意:给一些数,有两种操作,一种是在[a,b] 区间内,对(i - a)% k == 0 的加value,另一种操作是询问某个位置的值。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import