Different Integers
牛客一 J题 树状数组
题目描述
Given a sequence of integers a1, a2, ..., an and q pairs of integers (l1, r1), (l2, r2), ..., (lq, rq), find count(l1, r1), count(l2, r2), ..., count(lq, rq) where count(i, j) is the number of different integers among a1, a2, ..., ai, aj, aj + 1, ..., an.
输入描述:
The input consists of several test cases and is terminated by end-of-file.
The first line of each test cases contains two integers n and q.
The second line contains n integers a1, a2, ..., an.
The i-th of the following q lines contains two integers li and ri.
输出描述:
For each test case, print q integers which denote the result.
示例
输入
3 2
1 2 1
1 2
1 3
4 1
1 2 3 4
1 3
输出
2
1
3
备注:
- 1 ≤ n, q ≤ 105
- 1 ≤ ai ≤ n
- 1 ≤ li, ri ≤ n
- The number of test cases does not exceed 10.
题解
这场比赛的签到题 有很多种方法:莫队,主席树等 不过我不会
标程是树状数组,树状数组可以对区间进行跳跃性的操作。首先是题意,题意要求我们找[0,l]与[r,n]两个区间加起来不同的数,我看到标程将数组扩大一倍,就相当于找[r,l]区间不同的数,不过我觉得没有这个必要。
首先把那三个函数写好,套模板。
我们可以标记每个数字出现的前后位置,当遍历到一个数的最后一个数字后,从这个数开始的位置向上更新,这样可以快速更新这个位置之前有多少种数,(l前有多少种数并且结束的-r前有多少开始并结束的)=空缺区间有多少种数开始并已经结束,然后总的减去这个数就可以
下面是在百度辛苦折腾下终于AC的代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 5;
struct node
{
int l,r,num;
}f[maxn];
int s[maxn];
int pre[maxn];
int las[maxn];
int ans[maxn];
int tree[maxn];
int n;
bool cmp(node a,node b)
{
return a.r<b.r;
}
/* 树状数组函数模板*/
void add(int i, int v) {
while(i <= n+1) {
tree[i] += v;
i += i&-i;
}
}
int query(int i) {
int ret = 0;
while(i) {
ret += tree[i];
i -= i&-i;
}
return ret;
}
/*******************/
int main() {
int q;
int tot=0;
while(scanf("%d%d",&n,&q)!=EOF){
memset(pre,0,sizeof(pre));
memset(tree,0,sizeof(tree));
memset(las,0,sizeof(las));
tot=0;
for(int i=1;i<=n;i++){
scanf("%d",&s[i]);
if(!pre[s[i]]){
tot++;
pre[s[i]]=i;
}
las[s[i]]=i;
}
for(int i=1;i<=q;i++){
scanf("%d %d",&f[i].l,&f[i].r);
f[i].num=i;
}
int nowl=1;
sort(f+1,f+1+q,cmp);
for(int i=1;i<=n;i++){
while(nowl<=q&&f[nowl].r==i){
int num=f[nowl].num;
ans[num]=tot-(query(f[nowl].r)-query(f[nowl].l));
nowl++;
}
if(las[s[i]]==i) add(pre[s[i]],1);
}
for(int i=1;i<=q;i++) printf("%d\n",ans[i]);
}
}
Different Integers的更多相关文章
- [LeetCode] Sum of Two Integers 两数之和
Calculate the sum of two integers a and b, but you are not allowed to use the operator + and -. Exam ...
- [LeetCode] Divide Two Integers 两数相除
Divide two integers without using multiplication, division and mod operator. If it is overflow, retu ...
- HDU 1796How many integers can you find(容斥原理)
How many integers can you find Time Limit:5000MS Memory Limit:32768KB 64bit IO Format:%I64d ...
- Leetcode Divide Two Integers
Divide two integers without using multiplication, division and mod operator. 不用乘.除.求余操作,返回两整数相除的结果,结 ...
- LeetCode Sum of Two Integers
原题链接在这里:https://leetcode.com/problems/sum-of-two-integers/ 题目: Calculate the sum of two integers a a ...
- Nim Game,Reverse String,Sum of Two Integers
下面是今天写的几道题: 292. Nim Game You are playing the following Nim Game with your friend: There is a heap o ...
- POJ 3468 A Simple Problem with Integers(线段树 成段增减+区间求和)
A Simple Problem with Integers [题目链接]A Simple Problem with Integers [题目类型]线段树 成段增减+区间求和 &题解: 线段树 ...
- LeetCode 371. Sum of Two Integers
Calculate the sum of two integers a and b, but you are not allowed to use the operator + and -. Exam ...
- leetcode-【中等题】Divide Two Integers
题目 Divide two integers without using multiplication, division and mod operator. If it is overflow, r ...
- 解剖SQLSERVER 第十三篇 Integers在行压缩和页压缩里的存储格式揭秘(译)
解剖SQLSERVER 第十三篇 Integers在行压缩和页压缩里的存储格式揭秘(译) http://improve.dk/the-anatomy-of-row-amp-page-compre ...
随机推荐
- Springboot过滤器注解简笔
对多个过滤的注解 @WebFilter(filterName="FirstFilter",urlPatterns={"*.do","*.js ...
- CMakeLists添加内部库
SET(RTABMap_LIBRARIES ${PROJECT_SOURCE_DIR}/bin/librtabmap_core.so ${PROJECT_SOURCE_DIR}/bin/librtab ...
- 记Windows下初次使用dev C++进行socket编程过程
记初次接触socket编程,在devC++使用Winsock进行socket编程的一个过程,通过在devC++创建2个项目分别是server.client程序项目,感受通过socket使client与 ...
- VS2017中使用ReportViewer控件,vs2017找不到Microsoft Rdlc Report Designer for Visual Studio
VS2017中没有ReportViewer控件,这个控件用来实现在项目中显示和打印关系数据库中的表比较容易,特别是想要打印的时候,这个比用DataGridView和PrintDocument要简单一些 ...
- JAVA多线程的基础
线程与进程的区别 1.线程与进程 每个正在系统上运行的程序都是一个进程.每个进程包含一到多个线程.线程是一组指令的集合,或者是程序的特殊段,它可以在程序里独立执行.也可以把它理解为代码运行的上下文.所 ...
- php对象: __clone, __toString, __call,__isset, __unset, __sleep, __wakeup,
__clone: 克隆对象,自动完成操作 clone() __toString: return返回字符串 __call: 当调用不存在的函数时,自动执行该方法,并返回相关值 __isset: ...
- 1. rabbitmq 安装
1. ubuntu 16 18 安装 https://blog.csdn.net/haeasringnar/article/details/82715823 2. centos 7 https://w ...
- java this的用法以及原理
/** * this存在方法中,在方法中被调用. * 且是非static方法中被调用.(this 表示这个类的当前实例,而静态方法不依赖于该类的任何实例,随着类产生而装载,因此方法内不能引用 this ...
- matlab初级
命令 ======== 系统命令 命令 功能 例 date 显示当前日期 ans = 20-Jul-2019 what 当前文件夹下的matlab文件 type 文件中的内容 type CV.m ...
- G6:AntV 的图可视化与图分析
导读 G6 是 AntV 旗下的一款专业级图可视化引擎,它在高定制能力的基础上,提供简单.易用的接口以及一系列设计优雅的图可视化解决方案,是阿里经济体图可视化与图分析的基础设施.今年 AntV 11. ...