这题跟HDU3333差不多吧。

离线的做法很简单,不再说了

以前做过。

主席树的做法就比较暴力了。。

什么是主席树呢。。

其实是某种称号。

在该题中的体现是可持久化的线段树。

对于一个数

如果以前没出现过

就插入到主席树中

否则就删除以前那个。

再插入主席树。

注意,所有的更新和删除都是建立了新的节点来保持其历史状态的。。

对于T[i]我们存的是从1到i区间的不同的数出现了多少个。

然后这棵树是根据T[i - 1]来建立的。

代码如下。。第一次写主席树。 几乎是照着爱将的代码写的。

不过他是倒着来插入的,我是正向来的。 无非是一个以左端点为根查询。一个以询问的右端点为根查询,

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <map>
#include <vector>
#include <algorithm>
#define INF 111111111
#define MAXN 33333
#define MAXM 600005
using namespace std;
int n, tot, q, a[MAXN];
int T[MAXM], lson[MAXM], rson[MAXM], val[MAXM];
int nxt[MAXN], b[MAXN];
int build(int l, int r)
{
int rt = tot++;
val[rt] = 0;
int m = (l + r) >> 1;
if(l != r)
{
lson[rt] = build(l, m);
rson[rt] = build(m + 1, r);
}
return rt;
}
int update(int rt, int pos, int v)
{
int newrt = tot++, tmp = newrt;
int l = 1, r = n;
val[newrt] = val[rt] + v;
while(l < r)
{
int m = (l + r) >> 1;
if(pos <= m)
{
lson[newrt] = tot++;
rson[newrt] = rson[rt];
newrt = lson[newrt];
rt = lson[rt];
r = m;
}
else
{
rson[newrt] = tot++;
lson[newrt] = lson[rt];
newrt = rson[newrt];
rt = rson[rt];
l = m + 1;
}
val[newrt] = val[rt] + v;
}
return tmp;
} int query(int rt, int pos)
{
int ret = 0;
int l = 1, r = n;
while(pos > l)
{
int m = (l + r) >> 1;
if(pos <= m)
{
ret += val[rson[rt]];
rt = lson[rt];
r = m;
}
else
{
l = m + 1;
rt = rson[rt];
}
}
return ret + val[rt];
}
int main()
{
while(scanf("%d", &n) != EOF)
{
tot = 0;
memset(nxt, -1, sizeof(nxt));
for(int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
b[i - 1] = a[i];
}
sort(b, b + n);
int cnt = unique(b, b + n) - b;
T[0] = build(1, n);
for(int i = 1; i <= n; i++)
{
int id = lower_bound(b, b + cnt, a[i]) - b;
if(nxt[id] == -1)
T[i] = update(T[i - 1], i, 1);
else
{
int t = update(T[i - 1], nxt[id], -1);
T[i] = update(t, i, 1);
}
nxt[id] = i;
}
scanf("%d", &q);
while(q--)
{
int l, r;
scanf("%d%d", &l, &r);
printf("%d\n", query(T[r], l));
}
}
return 0;
}

SPOJ DQUERY 求区间内不同数的个数 主席树的更多相关文章

  1. 区间内x的出现个数(主席树)

    题目大概:求区间内x出现的次数 出题人yjy Description ZJK 给你一个长度为 n 的数列和 m 次询问,每次询问从第 l 个到第 r 个数中,数 x 出现了多少次.Input第一行一个 ...

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

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

  3. HDU4622:Reincarnation(后缀数组,求区间内不同子串的个数)

    Problem Description Now you are back,and have a task to do: Given you a string s consist of lower-ca ...

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

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

  5. HDU 3709 Balanced Number 求区间内的满足是否平衡的数量 (数位dp)

    平衡数的定义是指,以某位作为支点,此位的左面(数字 * 距离)之和 与右边相等,距离是指某位到支点的距离; 题意:求区间内满足平衡数的数量 : 分析:很好这又是常见的数位dp , 不过不同的是我们这次 ...

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

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

  7. SPOJ - DQUERY(区间不同数+树状数组)

    链接:SPOJ - DQUERY 题意:求给定区间不同数的个数(不更新). 题解:离线+树状数组. 对所求的所有区间(l, r)根据r从小到大排序.从1-n依次遍历序列数组,在树状数组中不断更新a[i ...

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

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

  9. SPOJ 3267 求区间不同数的个数

    题意:给定一个数列,每次查询一个区间不同数的个数. 做法:离线+BIT维护.将查询按右端点排序.从左到右扫,如果该数之前出现过,则将之前出现过的位置相应删除:当前位置则添加1.这样做就保证每次扫描到的 ...

随机推荐

  1. linux 备份日志文件

    seo说要备份文件,然后自己搞不定,每天一份文件.写了个shell,加了个crontab -e任务.每天执行一次. crontab: 59 23 * * * /root/sh/dumpApacheLo ...

  2. VC杂记

    获得Combobox的状态:向ComboBox发送CB_GETDROPPEDSTATE消息. 格式化字串:char buff[10] ; sprintf(buff,"1+1=%d" ...

  3. mongoengine教程1

    mongoengine安装过程,建议先安装好pip,pip是不Python不错的安装包管理器,安装命令:pip install mongoengine. mongoengine是mongodb的pyt ...

  4. go 语言与循环

    package main import "fmt" type Employee struct{name string; age int} func displayName(e *E ...

  5. Nginx配置免费SSL证书StartSSL,解决Firefox不信任问题

    先在StartSSL上申请免费一年的SSL证书,具体过程网上很多教程.然后把申请到的key和crt文件上传到服务器,比如/usr/local/nginx/certs/. Nginx配置SSL证书 直接 ...

  6. windows下端口被占用的解决方法

    1:打开CMD输入:netstat -ano | findstr "80" 找到PID: 2:查看应用名称:tasklist | findstr "2544" ...

  7. -AC自动机-题表

    2016-07-13 09:59:42

  8. gridview数据导出到word和excel以及excel的导入

    using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.UI ...

  9. Keil C51调试程序时, 对ROM的查看以及RAM 查看或修改

    在Keil 里使用 DeBug 模式时,如要 查看外部 RAM 的数据 或查看 ACC 的内容可以进行以下操作; sysGetTxMode: LCALL Com0185(C:2B95) ,sysGet ...

  10. VS2010编译、调用Lua程序

    一) .建立lua源代码工程,编译lua的静态库 1.下载Lua源码 http://www.lua.org/download.html a 下载后解压到一个目录下,这里假设解压到D:\lua-5.1. ...