SPOJ - DQUERY (主席树求区间不同数的个数)
2024-10-20 13:42:49
题目链接:https://vjudge.net/problem/SPOJ-DQUERY
题目大意:给定一个含有n个数的序列,有q个询问,每次询问区间[l,r]中不同数的个数。
解题思路:从左向右一个一个将该数字处在的位置添加到主席树中
如果该数字前面未出现过,则在此版本的线段树中的该条链加1,如果该数字已经出现过了,则在此版本线段树的上次出现位置减1,再在此版本线段树的该位置加1,这样就能保证区间不重复计算。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=;
struct node{
int l,r,sum;
}T[maxn*];
int n,q,a[maxn],cnt,root[maxn],pos[];
void update(int &now,int pre,int val,int l,int r,int pos){
T[++cnt]=T[pre],T[cnt].sum+=val,now=cnt;
if(l==r) return;
int mid=l+r>>;
if(pos<=mid) update(T[now].l,T[pre].l,val,l,mid,pos);
else update(T[now].r,T[pre].r,val,mid+,r,pos);
}
int query(int L,int R,int l,int r,int rt){
if(L<=l&&R>=r) return T[rt].sum;
int ans=,mid=l+r>>;
if(L<=mid) ans+=query(L,R,l,mid,T[rt].l);
if(R>mid) ans+=query(L,R,mid+,r,T[rt].r);
return ans;
}
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&a[i]);
for(int i=;i<=n;i++){
if(pos[a[i]]){
update(root[i],root[i-],-,,n,pos[a[i]]);
update(root[i],root[i],,,n,i);
}else update(root[i],root[i-],,,n,i);
pos[a[i]]=i;
}
scanf("%d",&q);
while(q--){
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",query(l,r,,n,root[r]));
}
return ;
}
最新文章
- 对路径的访问被拒绝,解决之后又报-未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”提供程序。
- vb---输入模式之文本输入与二进制输入区别
- H5常用代码:适配方案2
- Visual Studio 2015完全离线安装
- poj 题目分类(3)
- 关于微信聊天与朋友圈如何快速切换 Mark
- 有关于Algorithm的基础介绍
- Sightseeing Cows(最优比率环)
- linux 下vi中关于删除某段,某行,或者全部删除的命令
- 关于c语言变量的内存分布测试程序
- Tomcat 调优方案
- vue-element-admin项目install出现的问题
- 16.ajax_case03
- React页面隐藏#
- jQuery(八):属性操作
- Vue打开新页面的方法
- mysql 权限管理 针对库 授权 db.*
- 5.Longest Palindromic Substring (String; DP, KMP)
- LVM Linear vs Striped Logical Volumes
- mysql索引之主键索引
热门文章
- 运行PHP出现No input file specified错误解决办法
- Elasticsearch结构化搜索与查询
- wap开发tips
- 自定义类实现原生SQL的GROUP_CONCAT的功能
- Python分析《武林外传》 -----转载
- VMware 虚拟化编程(6) — VixDiskLib 虚拟磁盘库详解之二
- 【ABAP系列】SAP ALV 导出报表数据 始终使用选定的格式”,一旦勾上,就再也不会弹出选择框了。
- LeetCode——142 设计链表2
- C++笔记(4)——引用及结构体
- Dynamic Programming and Policy Evaluation