题意:找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 (主席树求区间不同数个数)的更多相关文章

  1. SPOJ - DQUERY 主席树求区间有多少个不同的数(模板)

    D-query Time Limit: 227MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu Submit Status ...

  2. hdu 5919--Sequence II(主席树--求区间不同数个数+区间第k大)

    题目链接 Problem Description Mr. Frog has an integer sequence of length n, which can be denoted as a1,a2 ...

  3. SPOJ - 3267. D-query 主席树求区间个数

    SPOJ - 3267 主席树的又一种写法. 从后端点开始添加主席树, 然后如果遇到出现过的元素先把那个点删除, 再更新树, 最后查询区间就好了. #include<bits/stdc++.h& ...

  4. 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) ...

  5. D-query SPOJ - DQUERY 主席树查询区间内不同数出现的次数

    我们不以权值建立主席树,而是区间端点作为值建立线段树,一个个插入a[i],我们发现这个数之前是存在的,就需要在上个版本的主席树上减去原来的位置,并加上现在的位置,这样我们在i版本的主席树,维护1-r中 ...

  6. SPOJ - DQUERY (主席树求区间不同数的个数)

    题目链接:https://vjudge.net/problem/SPOJ-DQUERY 题目大意:给定一个含有n个数的序列,有q个询问,每次询问区间[l,r]中不同数的个数. 解题思路:从左向右一个一 ...

  7. SPOJ 3267 D-query(离散化+主席树求区间内不同数的个数)

    DQUERY - D-query #sorting #tree English Vietnamese Given a sequence of n numbers a1, a2, ..., an and ...

  8. 主席树——求区间[l,r]不同数字个数的模板(向左密集 D-query)

    主席树的另一种用途,,(还有一种是求区间第k大,区间<=k的个数) 事实上:每个版本的主席树维护了每个值最后出现的位置 这种主席树不是以权值线段树为基础,而是以普通的线段树为下标的 /* 无修改 ...

  9. 主席树——求区间第k个不同的数字(向右密集hdu5919)

    和向左密集比起来向右密集只需要进行小小的额修改,就是更新的时候从右往左更新.. 自己写的被卡死时间.不知道怎么回事,和网上博客的没啥区别.. /* 给定一个n个数的序列a 每次询问区间[l,r],求出 ...

随机推荐

  1. flask之route中的参数

    flask的路由中有一些参数 使用案例 from flask import Flask, render_template, url_for, session, request, redirect ap ...

  2. 13.6 模拟事件【JavaScript高级程序设计第三版】

    事件,就是网页中某个特别值得关注的瞬间.事件经常由用户操作或通过其他浏览器功能来触发. 但很少有人知道,也可以使用JavaScript 在任意时刻来触发特定的事件,而此时的事件就如同浏览器创建的事件一 ...

  3. Logistic Regression学习笔记

    1.李航<统计学习方法>: 2.https://blog.csdn.net/laobai1015/article/details/78113214 3.http://www.cnblogs ...

  4. Linux(CentOS)安装Node.JS

    源码安装 比使用yum安装灵活 1.创建目录 cd /opt mkdir program cd program 2.下载安装包 wget https://nodejs.org/dist/v8.12.0 ...

  5. Linq工具篇(1)——使用LinqPad

    学习Linq,有一个非常强大的工具,那就是LinqPad,具体功能有多强大就不说了,网上百度一下就可以知道,百闻不如一见,用用就知道,在网上下载一个绿色版的,无需安装,直接运行,界面如下: 具体功能, ...

  6. How to find your web part

         When we deploy a web part, we can find it on any pages through the follow steps:      Firstly, ...

  7. sed 集合(项目中的笔记)

    奇数行和偶数行合并为一行: Like: Sequence number: 5398Sequence name: Glyma.16G123500.1Sequence number: 5399Sequen ...

  8. 【题解搬运】PAT_A1016 Phone Bills

    从我原来的博客上搬运.原先blog作废. 题目 A long-distance telephone company charges its customers by the following rul ...

  9. 多个excel合并(excel2007)

    1.新建一个空的excel文件,在需要合并的目录下. 2.右键点击sheet1,点击查看代码 3.执行此段代码 Sub 合并当前目录下所有工作簿的全部工作表() Dim MyPath, MyName, ...

  10. Jenkins - 持续集成部署

    1. 安装svn:用于checkout源码 (1)yum 安装:yum -y install subversion (2)查看svn版本信息:svnserver --version 2. 安装jdk ...