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

/**
按照数字所在的下标建立权值线段树
**/
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxx = ;
const int maxn = 1e6+;
struct node{
int l,r;
int cnt;
}tree[maxx*];
int cnt;
int a[maxx];
int pos[maxn];
int root[maxx];
void inserts(int l,int r,int pre,int &now,int pos,int w){
tree[++cnt]=tree[pre];
now=cnt;
tree[now].cnt+=w;
if (l==r){
return ;
}
int mid=(l+r)>>;
if (pos<=mid){
inserts(l,mid,tree[pre].l,tree[now].l,pos,w);
}else{
inserts(mid+,r,tree[pre].r,tree[now].r,pos,w);
}
}
int query(int rt,int l,int r,int ql,int qr){
if(ql<=l && r<=qr){
return tree[rt].cnt;
}
int mid=(l+r)>>;
if (qr<=mid){
return query(tree[rt].l,l,mid,ql,qr);
}else if (ql>mid){
return query(tree[rt].r,mid+,r,ql,qr);
}else{
return query(tree[rt].l,l,mid,ql,qr)+query(tree[rt].r,mid+,r,ql,qr);
}
}
int main(){
int n;
while(~scanf("%d",&n)){
cnt=;
memset(root,,sizeof(root));
memset(pos,,sizeof(pos));
for (int i=;i<=n;i++){
scanf("%d",&a[i]);
if (!pos[a[i]]){
inserts(,n,root[i-],root[i],i,);
pos[a[i]]=i;
}
else {
inserts(,n,root[i-],root[i],pos[a[i]],-);
inserts(,n,root[i],root[i],i,);
pos[a[i]]=i;
}
}
int q;
int l,r;
scanf("%d",&q);
while(q--){
scanf("%d%d",&l,&r);
printf("%d\n",query(root[r],,n,l,r));
}
}
return ;
}

D-query SPOJ - DQUERY 主席树查询区间内不同数出现的次数的更多相关文章

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

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

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

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

  3. A - 低阶入门膜法 - K-th Number (主席树查询区间第k小)

    题目链接:https://cn.vjudge.net/contest/284294#problem/A 题目大意:主席树查询区间第k小. 具体思路:主席树入门. AC代码: #include<i ...

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

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

  5. SPOJ - DQUERY 主席树

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=32356 Given a sequence of n numbers ...

  6. HDU 4417 Super Mario(主席树求区间内的区间查询+离散化)

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  7. HDU 4417 Super Mario 主席树查询区间小于某个值的个数

    #include<iostream> #include<string.h> #include<algorithm> #include<stdio.h> ...

  8. HDU 5919 - Sequence II (2016CCPC长春) 主席树 (区间第K小+区间不同值个数)

    HDU 5919 题意: 动态处理一个序列的区间问题,对于一个给定序列,每次输入区间的左端点和右端点,输出这个区间中:每个数字第一次出现的位子留下, 输出这些位子中最中间的那个,就是(len+1)/2 ...

  9. B - 低阶入门膜法 - D-query (查询区间内有多少不同的数)

    题目链接:https://cn.vjudge.net/contest/284294#problem/B 题目大意:查询区间内有多少个不相同的数. 具体思路:主席树的做法,主席树的基础做法是查询区间第k ...

随机推荐

  1. Lua报unexpected symbol near错误

    如果Lua脚本没有错误,那可能是UTF8 BOM的问题

  2. 洛谷P2426 删数 [2017年4月计划 动态规划12]

    P2426 删数 题目描述 有N个不同的正整数数x1, x2, ... xN 排成一排,我们可以从左边或右边去掉连续的i(1≤i≤n)个数(只能从两边删除数),剩下N-i个数,再把剩下的数按以上操作处 ...

  3. tomcat标准化安装

    操作系统说明: 操作系统 版本 linux red hat release 6.4 关键软件包说明: 软件包 版本 目录 运行用户 jdk-7u79-linux-x64.gz 1.7 /usr/loc ...

  4. Laravel Homestead: 403 forbidden on nginx, http://homestead.app访问不了

    起因:是因为Homestead.yaml 映射失败,一般是由于没有修改sites导致的, 正确的sites设置,类似于: 而很多人吧folders的配置看成是sites的配置了 解决方法: ①按照正确 ...

  5. 只需一步,DLA开启TableStore多元索引查询加速!

    一.背景介绍 Data Lake Analytics(简称DLA)在构建第一天就是支持直接关联分析Table Store(简称OTS)里的数据,实现存储计算分离架构,满足用户基于SQL接口分析Tabl ...

  6. 修改Eclipse自动换行长度

    使用Ctrl+Shift+F自动格式化代码的时候,有时候折行太多反而让代码看起来更乱,不容易阅读. 解决办法: Window-->Preferences-->Java-->Code ...

  7. [leetcode] Reverse Words in a String [1]

    一.题目: Given an input string, reverse the string word by word. For example, Given s = "the sky i ...

  8. PHP生成短连接的方法

    PHP生成短连接的方法.md PHP生成短连接的方法 直接贴上方法,函数可以查看手册. <?php /** 生成短网址 * @param String $url 原网址 * @return St ...

  9. CF274D

    Lenny had an n × m matrix of positive integers. He loved the matrix so much, because each row of the ...

  10. C语言获当地时间

    代码如下: #include <stdio.h> #include <time.h> #define DEBUGE 1 int main(void) { time_t rawt ...