【BZOJ】[SDOI2009]HH的项链
【算法】主席树||离线+树状数组
【题解】
主席树经典应用:找区间不同的数字个数。
做法:记录每个数上一次出现的位置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的项链的更多相关文章
- BZOJ 1878: [SDOI2009]HH的项链
1878: [SDOI2009]HH的项链 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 3548 Solved: 1757[Submit][Statu ...
- BZOJ 1878: [SDOI2009]HH的项链 离线树状数组
1878: [SDOI2009]HH的项链 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/p ...
- Bzoj 1878: [SDOI2009]HH的项链 莫队
1878: [SDOI2009]HH的项链 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 2717 Solved: 1363[Submit][Statu ...
- BZOJ 1878: [SDOI2009]HH的项链( BIT )
离线处理 , 记下询问的左右端点并排序 , 然后可以利用树状数组 , 保证查询区间时每种颜色只计算一次 ------------------------------------------------ ...
- bzoj千题计划181:bzoj1878: [SDOI2009]HH的项链
http://www.lydsy.com/JudgeOnline/problem.php?id=1878 之前用莫队做的,现在用树状数组 把每种数的第一个出现位置在树状数组中+1 nxt[i] 记录i ...
- BZOJ 1878 [SDOI2009]HH的项链 【莫队】
任意门:https://www.lydsy.com/JudgeOnline/problem.php?id=1878 1878: [SDOI2009]HH的项链 Time Limit: 4 Sec M ...
- 【BZOJ1878】[SDOI2009]HH的项链 离线BIT
1878: [SDOI2009]HH的项链 Description HH有一串由各种漂亮的贝壳组成的项链.HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一段贝壳,思考它们所表达的含义 ...
- Codevs 2307[SDOI2009]HH的项链
同题: Codevs 2307 HH的项链 BZOJ 1878 HH的项链 洛谷 1972 HH的项链 2009年省队选拔赛山东 时间限制: 1 s 空间限 ...
- 洛谷 P1972 [SDOI2009]HH的项链【莫队算法学习】
P1972 [SDOI2009]HH的项链 题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含 ...
- BZOJ_1878_[SDOI2009]HH的项链_莫队
BZOJ_1878_[SDOI2009]HH的项链_莫队 Description HH有一串由各种漂亮的贝壳组成的项链.HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一 段贝壳,思考 ...
随机推荐
- vs2015-Cordova开发安卓应用环境搭建
之前看到过用html5+css+js就可以开发跨平台的应用,然后发现vs2015里就有个Cordova项目所以就想试试,但并不是这么顺利.刚开始对安卓环境一点也不了解,就到处百度搜索.终于成功了. 首 ...
- 获取.jar文件运行时所处的路径
在Windows控制台中运行.jar文件时的两种环境: (1)控制台当前所在目录是.jar文件所在的目录 (2)控制台当前所在目录不是.jar文件所在的目录 我的期望: 我希望在上述两种环境下均可以得 ...
- 小程序如何去掉button组件的边框
小程序获取用户授权不再支持wx.getUserInfo方法,改为用button获取,格式如下 <button class="btn btn" open-type=" ...
- DDD领域驱动设计基本理论知识总结(转)
领域驱动设计之领域模型 为什么建立一个领域模型是重要的 领域通用语言(UBIQUITOUS LANGUAGE) 将领域模型转换为代码实现的最佳实践 领域建模时思考问题的角度 领域驱动设计的经典分层架构 ...
- coreos install hpssacli
基于官方的coreos ramdisk安装hp raid管理工具,其版本为debian8 apt-get install curl nano /etc/apt/sources.list deb htt ...
- KMP板子+Trie板子
KMP算法是一个字符串匹配算法,最直白的用法就是在一个长度为n的字符串T中查找另一个长度为m字符串P的匹配(总之就是用于文本中进行单个字符串的匹配). 对于这个问题,暴力算法是很好做的,直接对于T的每 ...
- 使用github同步网站
今天刚刚完成了自己的一个小项目,想把他上传到服务器上,想到到我使用的Visual Stdio Code具有git功能,于是想到使用github作为代码仓库来同步代码. 大体步骤分为这几步:创建远程代码 ...
- 将Excel表中的数据导入MySQL数据库
原文地址: http://fanjiajia.cn/2018/09/26/%E5%B0%86Excel%E8%A1%A8%E4%B8%AD%E7%9A%84%E6%95%B0%E6%8D%AE%E5% ...
- lintcode-49-字符大小写排序
49-字符大小写排序 给定一个只包含字母的字符串,按照先小写字母后大写字母的顺序进行排序. 注意事项 小写字母或者大写字母他们之间不一定要保持在原始字符串中的相对位置. 样例 给出"abAc ...
- win7 redis
<?php /* windows下php安装redis扩展 php_redis下载地址:https://pecl.php.net/package/redis 点击redis安装版本后面的 DLL ...