这题有离线和在线两种做法。

    离线:将查询区间按左端点排序,预处理出所有数下一次的出现位置,一开始将所有第一次出现的数a[i]++,之后当扫到这个数的时候a[next[i]]++,相当于差分,给之后的位置答案+1,因为查询区间左端点排序了,所以再也查不到当前点,这个数对答案有贡献的区间只有右端点在这个数下一次出现的位置右边的区间,当扫到查询区间左端点时当前答案为sum(r)-sum(l-1)。

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cmath>
#include<map>
#define ll long long
using namespace std;
const int maxn=,inf=1e9;
struct poi{int l,r,pos;}q[maxn];
int n,m,x,y,z,tot,N;
int tree[maxn],a[maxn],b[maxn],ans[maxn],next[maxn],pre[maxn];
bool v[maxn];
inline void read(int &k)
{
int f=;k=;char c=getchar();
while(c<''||c>'')c=='-'&&(f=-),c=getchar();
while(c<=''&&c>='')k=k*+c-'',c=getchar();
k*=f;
}
inline bool cmp(poi a,poi b){return a.l<b.l;}
inline int lowbit(int x){return x&-x;};
inline void add(int x){for(;x<=n;x+=lowbit(x))tree[x]++;}
inline int query(int x){int sum=;for(;x;x-=lowbit(x))sum+=tree[x];return sum;}
int main()
{
read(n);
for(int i=;i<=n;i++)read(a[i]),b[i]=a[i];N=n;
sort(b+,b++N);N=unique(b+,b++N)-b-;
for(int i=;i<=n;i++)a[i]=lower_bound(b+,b++N,a[i])-b;
for(int i=n;i;i--)next[i]=pre[a[i]],pre[a[i]]=i;
for(int i=;i<=n;i++)
if(!v[a[i]])add(i),v[a[i]]=;
read(m);
for(int i=;i<=m;i++)
{
read(q[i].l);read(q[i].r);
q[i].l--;q[i].pos=i;
}
sort(q+,q++m,cmp);
for(int i=,j=;i<=n&&j<=m;i++)
{
if(next[i])add(next[i]);
while(j<=m)
{
if(q[j].l!=i)break;
ans[q[j].pos]=query(q[j].r)-query(q[j].l);
j++;
}
}
for(int i=;i<=m;i++)printf("%d\n",ans[i]);
return ;
}

    在线:预处理出所有数上一次出现的位置,把问题转化成查询区间里有多少数last[i]<l,这显然可以用主席树了

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cmath>
#include<map>
#define ll long long
using namespace std;
const int maxn=,inf=1e9;
struct poi{int sum,lt,rt;}tree[maxn*];
int n,m,l,r,sz,N;
int root[maxn],pre[maxn],last[maxn],a[maxn],b[maxn];
void read(int &k)
{
int f=;k=;char c=getchar();
while(c<''||c>'')c=='-'&&(f=-),c=getchar();
while(c<=''&&c>='')k=k*+c-'',c=getchar();
k*=f;
}
void update(int &x,int l,int r,int cx)
{
tree[++sz]=tree[x];tree[sz].sum++;x=sz;
if(l==r)return;
int mid=(l+r)>>;
if(cx<=mid)update(tree[x].lt,l,mid,cx);
else update(tree[x].rt,mid+,r,cx);
}
int query(int x,int y,int l,int r,int cl,int cr)
{
if(cl<=l&&r<=cr)return tree[y].sum-tree[x].sum;
int mid=(l+r)>>,ret=;
if(cl<=mid)ret+=query(tree[x].lt,tree[y].lt,l,mid,cl,cr);
if(cr>mid)ret+=query(tree[x].rt,tree[y].rt,mid+,r,cl,cr);
return ret;
}
int main()
{
read(n);
for(int i=;i<=n;i++)read(a[i]),b[i]=a[i];N=n;
sort(b+,b++N);N=unique(b+,b++N)-b-;
for(int i=;i<=n;i++)a[i]=lower_bound(b+,b++N,a[i])-b;
for(int i=;i<=n;i++)pre[i]=last[a[i]],last[a[i]]=i;
for(int i=;i<=n;i++)update(root[i]=root[i-],,n,pre[i]);
read(m);
for(int i=;i<=m;i++)
{
read(l);read(r);
printf("%d\n",query(root[l-],root[r],,n,,l-));
}
}

bzoj1878: [SDOI2009]HH的项链(主席树/离线+BIT)的更多相关文章

  1. [bzoj1878][SDOI2009]HH的项链_树状数组

    HH的项链 bzoj-1878 SDOI-2009 题目大意:给定一个n个数的序列,m次查询.查询区间数的种类个数. 注释:$1\le n \le 5\cdot 10^4$,$1\le m\le 2\ ...

  2. [BZOJ1878][SDOI2009] HH的项链 (树状数组)

    link 一道简单题. 不用可持久化. 对于统计颜色个数,可以看与其颜色一样的前一个位置. 设$las(i)$表示其与$i$颜色相等的上一个位置. 则对于二元组$(l,r)$,其答案为$\sum_{i ...

  3. BZOJ1878 SDOI2009 HH的项链 【莫队】

    BZOJ1878 SDOI2009 HH的项链 Description HH有一串由各种漂亮的贝壳组成的项链.HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一段贝壳,思考它们所表达的 ...

  4. BZOJ1878: [SDOI2009]HH的项链 (离线查询+树状数组)

    1878: [SDOI2009]HH的项链 题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1878 Description: HH有一串由 ...

  5. bzoj千题计划181:bzoj1878: [SDOI2009]HH的项链

    http://www.lydsy.com/JudgeOnline/problem.php?id=1878 之前用莫队做的,现在用树状数组 把每种数的第一个出现位置在树状数组中+1 nxt[i] 记录i ...

  6. BZOJ1878: [SDOI2009]HH的项链[树状数组+离线 | 主席树]

    题意: 询问区间不同种类颜色数 [2016-11-15] 离线好厉害 对于每一个区间询问,一个数只考虑一次,那么考虑他最后出现的一次 将询问按r排序 从1到n扫描,用树状数组维护一个位置应不应该考虑( ...

  7. BZOJ1878: [SDOI2009]HH的项链[树状数组 离线]

    1878: [SDOI2009]HH的项链 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 3486  Solved: 1738[Submit][Statu ...

  8. BZOJ1878 [SDOI2009] HH的项链 [莫队,卡常]

    BZOJ传送门,洛谷传送门 HH的项链 Description HH有一串由各种漂亮的贝壳组成的项链.HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一 段贝壳,思考它们所表达的含义. ...

  9. [bzoj1878][SDOI2009]HH的项链_莫队

    HH 的项链 bzoj-1878 SDOI-2009 题目大意:给定一个n个数的序列.m次询问,每次询问一段区间内数的种类数. 注释:$1\le n\le 5\cdot 10^4$,$1\le m\l ...

随机推荐

  1. 「Python」Convert map object to numpy array in python 3

    转自Stackoverflow.备忘用. Question In Python 2 I could do the following: import numpy as np f = lambda x: ...

  2. 互联网行业求职课-教你进入BAT

    互联网行业求职课--教你进入BAT 课时1. 课程内容介绍.导师介绍.服务安排和介绍等 课时2. 互联网行业.职业选择指导 互联网公司选择: 大公司:收获:大平台,系统思维,系统培训,系统性的发展,薪 ...

  3. markdown语法介绍

    1. 标题类 每级标题用"# title"表示,共支持6级标题: 2. 段落类 1.建议用换行符控制: 2.用"<p></p>"控制: ...

  4. [精通Python自然语言处理] Ch1 - 将句子切分为单词

    实验对比了一下三种切分方式: 1,2 : nltk.word_tokenize :  分离缩略词,(“Don't” =>'Do', "n't") 表句子切分的“,” &quo ...

  5. jupyter notebook 使用cmd命令窗口打开

    第一步:将文件路径改为你需要使用文件所在的路径 第二部:   jupyter notebook

  6. Machine Learning笔记整理 ------ (五)决策树、随机森林

    1. 决策树 一般的,一棵决策树包含一个根结点.若干内部结点和若干叶子结点,叶子节点对应决策结果,其他每个结点对应一个属性测试,每个结点包含的样本集合根据属性测试结果被划分到子结点中,而根结点包含样本 ...

  7. MR execution in YARN

    Overview YARN provides API not for application developers but for the great developers working on ne ...

  8. 解决mac OS 10.9 下python 在terminal下崩溃的问题

    Python 2.7.6 release candidate 1 was released on October 26, 2013. This is a 2.7 series bugfix relea ...

  9. BZOJ 3924 ZJOI2015 幻想乡战略游戏 树链剖分

    题目链接:https://www.luogu.org/problemnew/show/P3345(bzoj权限题) 题意概述:动态维护树的上所有点到这棵树的带权重心的距离和.N,Q<=10000 ...

  10. 《剑指Offer》题六十一~题六十八

    六十一.扑克牌中的顺子 题目:从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的.2~10为数字本身,A为1,J为11,Q为12,K为13,而大.小王可以看成任意数字. 六十二.圆圈中 ...