SP3267 DQUERY - D-query (主席树)

简介: SP3267 DQUERY - D-query (主席树)

link

题意:

求区间出现的不同数字的种类数

思路:

方法有很多,莫队分块树状数组

对于主席树:

如果该元素第一次出现,直接将对应线段树的位置+ 1

反之,先将上一次出现的位置− 1,再将该位置+ 1

代码:

const int maxn=3e5+7,mod=1e9+7,inf=0x3f3f3f3f;
int a[maxn],n,q;
int root[maxn],idx;
struct node{
  int l,r,cnt;
}tr[maxn*40];
void pushup(int u){
  tr[u].cnt=tr[tr[u].l].cnt+tr[tr[u].r].cnt;
}
int build(int l,int r){
  int p=++idx;
  if(l==r){
    tr[p].cnt=0;
    return p;
  }
  int mid=(l+r)/2;
  tr[p].l=build(l,mid);
    tr[p].r=build(mid+1,r);
    pushup(p);
    return p;
}
int nsert(int k,int l,int r,int u,int val){
  int p=++idx;
  tr[p]=tr[u];
  if(l==k&&k==r){
    tr[p].cnt+=val;return p;
  }
  int mid=(l+r)/2;
  if(k<=mid) tr[p].l=nsert(k,l,mid,tr[p].l,val);
  else tr[p].r=nsert(k,mid+1,r,tr[p].r,val);
  pushup(p);
  return p;
}
int query(int l,int r,int u,int pos){
  if(l==r) return tr[u].cnt;
  int mid=(l+r)/2;
  if(pos<=mid) return tr[tr[u].r].cnt+query(l,mid,tr[u].l,pos);
  else return query(mid+1,r,tr[u].r,pos);
}
int main(){
  n=read;
  rep(i,1,n) a[i]=read;
  root[0]=build(1,n);
  map<int,int>mp;
  rep(i,1,n){
    if(!mp[a[i]]){
      mp[a[i]]=i;
      root[i]=nsert(i,1,n,root[i-1],1);
    }
    else{
      int tmp=nsert(mp[a[i]],1,n,root[i-1],-1);
      root[i]=nsert(i,1,n,tmp,1);
    }
    mp[a[i]]=i;
  }
  q=read;
  while(q--){
    int l=read,r=read;
    printf("%d\n",query(1,n,root[r],l));
  }
}
/**
 * root[i]维护的是数组[1,i]中每个数的最后位置
这样查询 [ l , r ] 内的答案就是查询第 r 个版本的主席树中 [ l , r ] 的 sum
 * */
目录
相关文章
|
9天前
|
Java
开发指南004-@Query参数写法
JPA的Query注解和函数参数的绑定有多种写法
|
9月前
|
SQL 关系型数据库 MySQL
SQL聚合函数SUM值为NULL引发的爆炸
在写这篇文章之前,最想提醒大家的是,开发一定不能想当然,看着没问题就不调试了,结果它就是有问题的。如果时间很紧,到了测试阶段才发现问题解决问题那就很狼狈很被动了,不要问我为什么会特别想提这个。
93 0
SQL聚合函数SUM值为NULL引发的爆炸
SP10707 COT2 - Count on a tree II(欧拉序 树上莫队)
SP10707 COT2 - Count on a tree II(欧拉序 树上莫队)
87 0
SP10707 COT2 - Count on a tree II(欧拉序 树上莫队)
codeForces416——B.Art Union(模拟)
codeForces416——B.Art Union(模拟)
51 0
codeForces416——B.Art Union(模拟)
|
SQL 数据挖掘 Python
SQL练习:2(简单)+1(中等),常规题(group by\order by\avg...)
SQL练习:2(简单)+1(中等),常规题(group by\order by\avg...)
162 0
SQL练习:2(简单)+1(中等),常规题(group by\order by\avg...)
One order search dynamic sql statement生成位置
One order search dynamic sql statement生成位置
One order search dynamic sql statement生成位置
|
SQL Go
【SQL】ROW_NUMBER() OVER(partition by 分组列 order by 排序列)用法详解+经典实例
【SQL】ROW_NUMBER() OVER(partition by 分组列 order by 排序列)用法详解+经典实例目录 0、填充数据1、使用row_number()函数对订单进行编号,按照订单时间倒序。
12392 0
|
SQL 数据库
简单实用SQL脚本Part:查找SQL Server 自增ID值不连续记录
原文:简单实用SQL脚本Part:查找SQL Server 自增ID值不连续记录        在很多的时候,我们会在数据库的表中设置一个字段:ID,这个ID是一个IDENTITY,也就是说这是一个自增ID。
1681 0