SPOJ DQUERY (主席树求区间不同数个数)
题意:找n个数中无修改的区间不同数个数
题解:使用主席树在线做,我们不能使用权值线段树建主席树
我们需要这么想:从左向右添加一到主席树上,添加的是该数字处在的位置
但是如果该数字前面出现过,就在此版本的主席树上的前面出现的位置减一,接着才在此位置上添一
这样查找是按照右区间版本的主席树来找(lef,rig)的数字
因为要将此区间每个不同的数都处在最后出现的位置
/*在线求区间内不同的数的个数:从头到尾添加到线段树(不是权值线段树,是存值的线段树)中
如果此数之前出现过就先减去,接着再加,最后在区间(l,r)中找到root[r]这个历史版本*/
#include<map>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define dir(a,b) (a>>b)
const int Max=;
int root[Max],tot,val[Max];
struct node
{
int lef,rig,sum;
}msegtr[Max*];
map<int,int> mp;
void Init()
{
tot=;
msegtr[].lef=msegtr[].rig=msegtr[].sum=;
root[]=;
mp.clear();
return;
}
void Create(int sta,int enn,int &x,int y,int pos,int aad)
{
msegtr[++tot]=msegtr[y];
msegtr[tot].sum+=aad;
x=tot;
if(sta==enn)
return;
int mid=dir(sta+enn,);
if(mid>=pos)
Create(sta,mid,msegtr[x].lef,msegtr[y].lef,pos,aad);
else
Create(mid+,enn,msegtr[x].rig,msegtr[y].rig,pos,aad);
return;
}
int Query(int sta,int enn,int x,int y)//只有左边有界限
{
if(sta>=y)
return msegtr[x].sum;
int mid=dir(sta+enn,);
if(mid>=y)
return Query(sta,mid,msegtr[x].lef,y)+msegtr[msegtr[x].rig].sum;
else
return Query(mid+,enn,msegtr[x].rig,y);
}
int main()
{
int n,m,temp;
int lef,rig;
while(~scanf("%d",&n))
{
Init();
for(int i=;i<=n;++i)
{
scanf("%d",&val[i]);
if(!mp.count(val[i]))//直接加
{
Create(,n,root[i],root[i-],i,);//注意是在i这个位置加1,不是权值线段树的val[i]位置加1
}
else
{
Create(,n,temp,root[i-],mp[val[i]],-);//先在原位置减去1
Create(,n,root[i],temp,i,);
}
mp[val[i]]=i;
}
scanf("%d",&m);
for(int i=;i<m;++i)
{
scanf("%d %d",&lef,&rig);
printf("%d\n",Query(,n,root[rig],lef));//在rig的历史版本上找(lef,rig)的值
}
}
return ;
}
SPOJ DQUERY (主席树求区间不同数个数)的更多相关文章
- SPOJ - DQUERY 主席树求区间有多少个不同的数(模板)
D-query Time Limit: 227MS Memory Limit: 1572864KB 64bit IO Format: %lld & %llu Submit Status ...
- hdu 5919--Sequence II(主席树--求区间不同数个数+区间第k大)
题目链接 Problem Description Mr. Frog has an integer sequence of length n, which can be denoted as a1,a2 ...
- SPOJ - 3267. D-query 主席树求区间个数
SPOJ - 3267 主席树的又一种写法. 从后端点开始添加主席树, 然后如果遇到出现过的元素先把那个点删除, 再更新树, 最后查询区间就好了. #include<bits/stdc++.h& ...
- SPOJ:D-query(非常规主席树求区间不同数的个数)
Given a sequence of n numbers a1, a2, ..., an and a number of d-queries. A d-query is a pair (i, j) ...
- D-query SPOJ - DQUERY 主席树查询区间内不同数出现的次数
我们不以权值建立主席树,而是区间端点作为值建立线段树,一个个插入a[i],我们发现这个数之前是存在的,就需要在上个版本的主席树上减去原来的位置,并加上现在的位置,这样我们在i版本的主席树,维护1-r中 ...
- SPOJ - DQUERY (主席树求区间不同数的个数)
题目链接:https://vjudge.net/problem/SPOJ-DQUERY 题目大意:给定一个含有n个数的序列,有q个询问,每次询问区间[l,r]中不同数的个数. 解题思路:从左向右一个一 ...
- SPOJ 3267 D-query(离散化+主席树求区间内不同数的个数)
DQUERY - D-query #sorting #tree English Vietnamese Given a sequence of n numbers a1, a2, ..., an and ...
- 主席树——求区间[l,r]不同数字个数的模板(向左密集 D-query)
主席树的另一种用途,,(还有一种是求区间第k大,区间<=k的个数) 事实上:每个版本的主席树维护了每个值最后出现的位置 这种主席树不是以权值线段树为基础,而是以普通的线段树为下标的 /* 无修改 ...
- 主席树——求区间第k个不同的数字(向右密集hdu5919)
和向左密集比起来向右密集只需要进行小小的额修改,就是更新的时候从右往左更新.. 自己写的被卡死时间.不知道怎么回事,和网上博客的没啥区别.. /* 给定一个n个数的序列a 每次询问区间[l,r],求出 ...
随机推荐
- MySQL数据操作(DML)
表结构准备: mysql> CREATE TABLE student( -> sid INT PRIMARY KEY AUTO_INCREMENT, ), -> age INT, ) ...
- ReentrantLock详解
ReentrantLock概述 ReentrantLock是Lock接口的实现类,可以手动的对某一段进行加锁.ReentrantLock可重入锁,具有可重入性,并且支持可中断锁.其内部对锁的控制有两种 ...
- VSCode插件整理
VSCode插件整理 VSCode插件整理 官网地址 vscode常用配置(User Settings文件) 基本插件 前端插件 VUE部分 python MarkDown部分 连接Linux 本地与 ...
- python函数(2017-8-2)
1. def 函数名(形式参数) 函数体 return "123" 函数执行了return之后就不再执行下面的代码 2. 默认形参实参的位置一一对应 如果要调整位置,指定形参名字 ...
- R语言绘图:箱线图
使用ggplot2绘制箱线图 ######*****绘制箱线图代码*****####### data1$学区房 <- factor(data1$school, levels = 0:1, lab ...
- HDU1301 Jungle Roads(Kruskal)
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission( ...
- STL 一些常用的STL函数(持续更新
先说一下 一边要用到算法的东西一般要加#include<algorithm>头文件 一.栈和队列 1 栈 :一种线性表 特点 后进先出 头文件 #include<stack&g ...
- C# 面试题 (一)
一.C# 理论 1.1.简述 private. protected. public. internal.protected internal 访问修饰符和访问权限 private : 私有成员, 在类 ...
- elasticsearch 关联查询
父-子关系文档 父-子关系文档 在实质上类似于 nested model :允许将一个对象实体和另外一个对象实体关联起来. 而这两种类型的主要区别是:在 nested objects 文档中,所有对象 ...
- es同步mysql同步-logstash
1.下载es https://www.elastic.co/downloads/elasticsearch 修改 config 下elasticsearch.yml ip和端口等配置 2.下载ki ...