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 ...
随机推荐
- Lock wait timeout exceeded; try restarting transaction(mysql事务锁)
现场环境客户要求删数据(界面没法直接操作),于是直接在数据库进行查询删除了,删完发现界面依然能查到删除后的数据,又用sql语句进行删除,发现报了错:Lock wait timeout exceeded ...
- pytorch 自动求梯度
自动求梯度 在深度学习中,我们经常需要对函数求梯度(gradient).PyTorch提供的autograd包能够根据输入和前向传播过程自动构建计算图,并执行反向传播.本节将介绍如何使用autogra ...
- 吴裕雄--天生自然MySQL学习笔记:MySQL 插入数据
MySQL 表中使用 INSERT INTO SQL语句来插入数据. 可以通过 mysql> 命令提示窗口中向数据表中插入数据,或者通过PHP脚本来插入数据. 以下为向MySQL数据表插入数据通 ...
- Linux 常用命令全拼
pwd: print work directory 打印当前目录 显示出当前工作目录的绝对路径 ps: process status(进程状态,类似于windows的任务管理器) 常用参数:-auxf ...
- Thread--线程间通信--管道
在Java语言中提供了各种各样的输入/输出流Stream,使我们能够方便的对数据进行操作,其中管道流是一种特殊的流,用于在不同线程间直接传送数据.一个线程发送数据到输出管道,另一个线程从输入管道中读数 ...
- 分糖果(BFS)
题目描述 童年的我们,将和朋友分享美好的事物作为自己的快乐.这天,C小朋友得到了糖果,将要把这些糖果分给要好的朋友们.已知糖果从一个人传给另一个人需要1秒的时间,同一个小朋友不会重复接受糖果.由于糖果 ...
- Java8之深入理解Lambda
lambda表达式实战 从例子引出lambda 传递Runnable创建Thread java8之前 Thread thread=new Thread(new Runnable() { @Overri ...
- c#之初识结构(Struct)
C# 结构(Struct) 首先结构是值类型数据结构.它使得一个单一变量可以存储各种数据类型的相关数据.struct 关键字用于创建结构.通俗说:结构就是一个可以包含不同数据类型的集合.它是一种可以自 ...
- Java之同步方法处理实现Runnable接口的线程安全问题
/** * 使用同步方法解决实现Runnable接口的线程安全问题 * * * 关于同步方法的总结: * 1. 同步方法仍然涉及到同步监视器,只是不需要我们显式的声明. * 2. 非静态的同步方法,同 ...
- 游程编码run length code
今天突然看到一个名词,游程编码.也叫行程编码. 简单理解就是,几个相同连续的字符,然后用数字统计表示. 举个例子: aaaabbbccc 用游程编码的表示就是4a3b3c 如果:连续字符只有一个 那么 ...