【算法】主席树||离线+树状数组

【题解】

主席树经典应用:找区间不同的数字个数。

做法:记录每个数上一次出现的位置last[i],对last建权值线段树,对于区间询问last[i]<L的数字个数。

注意权值范围是last[i],也即0~n。

注意x=0时返回,否则可能c<0就完了。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cctype>
using namespace std;
const int maxn=;
struct tree{int l,r,sum;}t[];
int a[maxn],n,sz,last[maxn],root[maxn],b[],m; int read()
{
char c;int s=,t=;
while(!isdigit(c=getchar()))if(c=='-')t=-;
do{s=s*+c-'';}while(isdigit(c=getchar()));
return s*t;
}
void insert(int l,int r,int &x,int y,int c){
x=++sz;
t[x]=t[y];t[x].sum++;
if(l==r)return;
int mid=(l+r)>>;
if(c<=mid)insert(l,mid,t[x].l,t[y].l,c);
else insert(mid+,r,t[x].r,t[y].r,c);
}
int ask(int l,int r,int x,int c){
if(x==)return ;
if(r<=c)return t[x].sum;
int mid=(l+r)>>,ans=;
if(c>mid)ans+=ask(mid+,r,t[x].r,c);
ans+=ask(l,mid,t[x].l,c);
return ans;
}
int main(){
n=read();
for(int i=;i<=n;i++){
a[i]=read();
last[i]=b[a[i]];
b[a[i]]=i;
}
for(int i=;i<=n;i++)insert(,n,root[i],root[i-],last[i]);
m=read();
for(int i=;i<=m;i++){
int u=read(),v=read();
printf("%d\n",ask(,n,root[v],u-)-ask(,n,root[u-],u-));
}
return ;
}

另一种做法,考虑对询问离线并按左端点排序,那么一个位置对答案有贡献仅当左端点已经过和它相同数字的上一位置,那么就是求区间和(有贡献的点+1),显然是树状数组。

具体过程:初始同一个数字最前面的位置+1,然后1~n每次nex[i]位置+1,同时回答询问ans=ask(r)-ask(l-1),因为左端点经过了所以区间同一个数最多只存在一个。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cctype>
#define lowbit(x) x&(-x)
using namespace std;
const int maxn=,maxL=;
int a[maxn],c[maxn],n,m,ans[maxn],anss[maxn],nex[maxn],b[maxL]; int read()
{
char c;int s=,t=;
while(!isdigit(c=getchar()))if(c=='-')t=-;
do{s=s*+c-'';}while(isdigit(c=getchar()));
return s*t;
}
struct cyc{int l,r,id;}d[maxn];
bool cmp(cyc a,cyc b){return a.l<b.l;}
void insert(int x){for(int i=x;i<=n;i+=lowbit(i))c[i]++;}
int ask(int x){int nowans=;for(int i=x;i>=;i-=lowbit(i))nowans+=c[i];return nowans;}
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++){
a[i]=read();
}
for(int i=;i<=maxL;i++)b[i]=n+;
for(int i=n;i>=;i--){
nex[i]=b[a[i]];
b[a[i]]=i;
}
for(int i=;i<=maxL;i++)if(b[i])insert(b[i]);
scanf("%d",&m);
for(int i=;i<=m;i++){
d[i].l=read();d[i].r=read();
d[i].id=i;
}
sort(d+,d+m+,cmp);
int now=;
for(int i=;i<=n&&now<=m;i++){
while(now<=m&&d[now].l==i){ans[now]=ask(d[now].r)-ask(d[now].l-);now++;}
insert(nex[i]);
}
for(int i=;i<=m;i++)anss[d[i].id]=ans[i];
for(int i=;i<=m;i++)printf("%d\n",anss[i]);
return ;
}

常数约为主席树的1/2。

【BZOJ】[SDOI2009]HH的项链的更多相关文章

  1. BZOJ 1878: [SDOI2009]HH的项链

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

  2. BZOJ 1878: [SDOI2009]HH的项链 离线树状数组

    1878: [SDOI2009]HH的项链 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/p ...

  3. Bzoj 1878: [SDOI2009]HH的项链 莫队

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

  4. BZOJ 1878: [SDOI2009]HH的项链( BIT )

    离线处理 , 记下询问的左右端点并排序 , 然后可以利用树状数组 , 保证查询区间时每种颜色只计算一次 ------------------------------------------------ ...

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

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

  6. BZOJ 1878 [SDOI2009]HH的项链 【莫队】

    任意门:https://www.lydsy.com/JudgeOnline/problem.php?id=1878 1878: [SDOI2009]HH的项链 Time Limit: 4 Sec  M ...

  7. 【BZOJ1878】[SDOI2009]HH的项链 离线BIT

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

  8. Codevs 2307[SDOI2009]HH的项链

    同题:     Codevs 2307 HH的项链     BZOJ    1878 HH的项链     洛谷      1972 HH的项链 2009年省队选拔赛山东  时间限制: 1 s  空间限 ...

  9. 洛谷 P1972 [SDOI2009]HH的项链【莫队算法学习】

    P1972 [SDOI2009]HH的项链 题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含 ...

  10. BZOJ_1878_[SDOI2009]HH的项链_莫队

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

随机推荐

  1. Apache 配置说明

    ServerRoot ServerRoot: The top of the directory tree under which the server's configuration, error, ...

  2. 代码混淆 iOS

    该方法只能针对有.m.h的类进行混淆,静态库等只有.h文件的没法进行混淆 代码混淆,刚刚看到是不是有点懵逼,反正我是最近才接触到这么个东西,因为之前对于代码和APP,只需要实现功能就好了,根本没有考虑 ...

  3. 西门子S7-200 SMART在win10环境下,使用虚拟机进行网络通信问题一二

    原来的笔记本光荣退休,新买了小米笔记本17150.有个项目需要使用西门子S7-200 SMART,结果碰到了很多悲催的事情,新系统下的各种问题. 先贴下计算机配置,如下: 阶段一:安装问题 (1)在w ...

  4. python 基础篇 10 函数进阶

    本节主要内容:1. 函数参数--动态传参2. 名称空间, 局部名称空间, 全局名称空间, 作⽤域, 加载顺序.3. 函数的嵌套4. gloabal, nonlocal关键字 ⼀. 函数参数--动态传参 ...

  5. [leetcode-646-Maximum Length of Pair Chain]

    You are given n pairs of numbers. In every pair, the first number is always smaller than the second ...

  6. 在Android Studio中创建(或添加)第一个Hello World应用程序

    下面我们将使用Android Studio创建第一个简单的Hello World应用程序. 1.打开Android Studio,加载画面如下图所示:   2.选择”Start a new Andro ...

  7. 最大流——EK算法

    一.算法理论 [基本思想] 反复寻找源点s到汇点t之间的增广路径,若有,找出增广路径上每一段[容量-流量]的最小值delta,若无,则结束.在寻找增广路径时,可以用BFS来找,并且更新残留网络的值(涉 ...

  8. Z.XML第一次迭代分数分配

    紧张的第一次迭代落下帷幕,便到了分数分配这样令人揪心又无奈的日子.如何进行分数分配,以使大家都能满意,这一直是个难以非常好地处理的问题.幸运地是,我们团队的所有成员每个人都对本次迭代乃至整个项目过程付 ...

  9. Python-爬取"我去图书馆"座位编码

    原文地址:http://fanjiajia.cn/2018/11/22/Python-%E7%88%AC%E5%8F%96%E2%80%9D%E6%88%91%E5%8E%BB%E5%9B%BE%E4 ...

  10. PHPExcel 导出包含图片excel

    <?php // 这里用的PHPExcel版本号为1.8.0 // 下载地址https://github.com/PHPOffice/PHPExcel 下载ZIP压缩包 // 下载后将Class ...