洛谷 P1972 [SDOI2009]HH的项链——树状数组
先上一波题目 https://www.luogu.org/problem/P1972
这道题是询问区间内不同数的个数 明显不是正常的数据结构能够维护的
首先考虑 因为对于若干个询问的区间[l,r],如果他们的r都相等的话,那么项链中出现的同一个数字,一定是只关心出现在最右边的那一个的
例如项链:1 3 4 5 1
那么,对于r=5的所有的询问来说,第一个位置上的1完全没有意义,因为r已经在第五个1的右边,对于任何查询的[L,5]区间来说,如果第一个1被算了,那么他完全可以用第五个1来替代。
那么我们将询问按右端点从小到大进行排序 利用数据结构维护前缀和 涉及的操作有单点修改和区间(前缀和)查询
这样每次我们更新一个点的时候 就可以将和他同颜色的上一个点的影响消除 即将上一个点所在的位置-1 然后将当前点位置+1
这样问题就解决了qwq
然而这道题对线段树并不友好(可能我写的太丑了加上数据又加强了)T了一个点
经过各种玄学修改 比如将结构体换成数组 加上inline 甚至在读入优化的基础上 加上输出优化 还是T掉了qwq
但毕竟也算是正解 就挂一下好了
涉及的操作就是单点修改和区间求和了
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
const int M=1e6+;
int read(){
int ans=,f=,c=getchar();
while(c<''||c>''){if(c=='-') f=-; c=getchar();}
while(c>=''&&c<=''){ans=ans*+(c-''); c=getchar();}
return ans*f;
}
int n,m,s[M];
int last[M],ans[M];
struct node{int l,r,sum;}e[*M];
struct qwq{int id,l,r;}q[M];
int cmp(qwq x,qwq y){return x.r<y.r;}
void up(int x){e[x].sum=e[x<<].sum+e[x<<^].sum;}
void build(int x,int l,int r){
e[x].l=l; e[x].r=r;
if(l==r) return ;
int mid=l+r>>;
build(x<<,l,mid);
build(x<<^,mid+,r);
}
void del(int x,int D){
if(e[x].l==e[x].r&&e[x].l==D){
e[x].sum=;
return ;
}
int mid=e[x].l+e[x].r>>;
if(D<=mid) del(x<<,D);
if(D>mid) del(x<<^,D);
up(x);
}
void add(int x,int D){
if(e[x].l==e[x].r&&e[x].l==D){
e[x].sum=;
return ;
}
int mid=e[x].l+e[x].r>>;
if(D<=mid) add(x<<,D);
if(D>mid) add(x<<^,D);
up(x);
}
int p_ans(int x,int L,int R){
if(L>R) return ;
if(L<=e[x].l&&e[x].r<=R) return e[x].sum;
int ans=,mid=e[x].l+e[x].r>>;
if(L<=mid) ans+=p_ans(x<<,L,R);
if(R>mid) ans+=p_ans(x<<^,L,R);
return ans;
}
int main(){
n=read(); build(,,n);
for(int i=;i<=n;i++) s[i]=read();
m=read();
for(int i=;i<=m;i++) q[i].l=read(),q[i].r=read(),q[i].id=i;
sort(q+,q++m,cmp);
// for(int i=1;i<=m;i++) printf("qwq%d %d\n",q[i].l,q[i].r);
int x=;
for(int i=;i<=m;i++){
while(x<=q[i].r){
if(last[s[x]]) del(,last[s[x]]);
add(,x); last[s[x]]=x;
x++;
}
ans[q[i].id]=p_ans(,,q[i].r)-p_ans(,,q[i].l-);
// printf("qaq%d\n",x); }
for(int i=;i<=m;i++) printf("%d\n",ans[i]);
return ;
}
第二种做法自然就是树状数组了 树状数组的常数果然比线段树要小很多 跑得飞快
涉及的操作自然就是单点修改和求前缀和了
也算是复习了一波树状数组 这里挂一个大大的优秀讲解好了 https://www.cnblogs.com/xenny/p/9739600.html
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define lowbit(x) x&(-x)
using namespace std;
const int M=1e6+;
int read(){
int ans=,f=,c=getchar();
while(c<''||c>''){if(c=='-') f=-; c=getchar();}
while(c>=''&&c<=''){ans=ans*+(c-''); c=getchar();}
return ans*f;
}
int n,m,s[M],sum[M*];
int last[M],ans[M];
struct qwq{int id,l,r;}q[M];
int cmp(qwq x,qwq y){return x.r<y.r;}
void update(int x,int k){
while(x<=n){
sum[x]+=k;
x+=lowbit(x);
}
}
int p_ans(int x){
int ans=;
while(x){
ans+=sum[x];
x-=lowbit(x);
}
return ans;
}
int main(){
n=read();
for(int i=;i<=n;i++) s[i]=read();
m=read();
for(int i=;i<=m;i++) q[i].l=read(),q[i].r=read(),q[i].id=i;
sort(q+,q++m,cmp);
int x=;
for(int i=;i<=m;i++){
while(x<=q[i].r){
if(last[s[x]]) update(last[s[x]],-);
update(x,); last[s[x]]=x;
x++;
}
ans[q[i].id]=p_ans(q[i].r)-p_ans(q[i].l-);
}
for(int i=;i<=m;i++) printf("%d\n",ans[i]);
return ;
}
洛谷 P1972 [SDOI2009]HH的项链——树状数组的更多相关文章
- 【题解】P1972 [SDOI2009]HH的项链 - 树状数组
P1972 [SDOI2009]HH的项链 声明:本博客所有题解都参照了网络资料或其他博客,仅为博主想加深理解而写,如有疑问欢迎与博主讨论✧。٩(ˊᗜˋ)و✧*。 题目描述 \(HH\) 有一串由各种 ...
- luogu P1972 [SDOI2009]HH的项链 |树状数组 或 莫队
题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不断地收集新的贝壳,因此,他的项链变得越来越长. ...
- 洛谷——P1972 [SDOI2009]HH的项链(线段树)
P1972 [SDOI2009]HH的项链 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不断地收集新的 ...
- 洛谷 P1972 [SDOI2009]HH的项链-二维偏序+树状数组+读入挂(离线处理,思维,直接1~n一边插入一边查询),hahahahahahaha~
P1972 [SDOI2009]HH的项链 题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含 ...
- 洛谷 P1972 [SDOI2009]HH的项链 解题报告
P1972 [SDOI2009]HH的项链 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不断 ...
- 洛谷 P1972 [SDOI2009]HH的项链【莫队算法学习】
P1972 [SDOI2009]HH的项链 题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含 ...
- 洛谷P1972 [SDOI2009]HH的项链(树状数组)
题目链接: https://www.luogu.org/problemnew/show/P1972 题目描述: HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后 ...
- 洛谷 P1972 [SDOI2009]HH的项链(树状数组,离线)
传送门 解题思路 因为是求区间的不同种类数,所以我们用树状数组(貌似并没有什么直接联系) (...表示到) 还是和原来一样,用s[i]来表示a[i-lowbit(i)]...a[i]的种类数. 因为有 ...
- 洛谷 P1972"[SDOI2009]HH的项链"(离线+树状数组 or 在线+主席树)
传送门 •题意 给你一个包含 n 个数的数组 $a$: 有 m 此操作,每次操作求区间 [l,r] 中不同数的个数: •题解(离线+树状数组) 以样例 $[1,2,3,4,3,5]$ 为例,求解区间 ...
随机推荐
- IIS 应用池资源定时回收
方法1: 方法2:
- ajax axios 下载文件时如何获取进度条 process
最近项目需要做一个下载文件的进度条,看网上上传文件进度条下载,特分享出来方便大家查阅 <!DOCTYPE html> <html> <head> <m ...
- Error: Chunk.entrypoints: Use Chunks.groupsIterable and filter by instanceof Entrypoint instead
一.extrack-tex-webpack-plugin作用:为了抽离css样式,防止将样式打包在js中引起页面样式加载错乱的现象二.使用 npm install extract-webpack-pl ...
- 微信小程序(6)--获取屏幕宽度及弹窗滚动与页面滚动冲突
1.获取屏幕宽度,并赋值给view <view class="ships-img" style="height:{{windowWidth}}px;"&g ...
- 牛客小白月赛16 F 小石的妹子 (线段树)
链接:https://ac.nowcoder.com/acm/contest/949/F来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言52428 ...
- 1、pip不是内部运行程序 解决方法
一.方式一 1.切换到pip所在路径: shit+ 右键. 再此处打开运行窗口 2.执行 pip install pytest 脚本即可. 二.方式二,添加环境变量 1.将pip所在的文件路径 添加到 ...
- bzoj5161 最长上升子序列 状压DP(DP 套 DP) + 打表
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=5161 题解 回顾一下以前用二分求 LIS 的方法:令 \(f[i]\) 表示长度为 \(i\) ...
- call_user_func_array — 调用回调函数,并把一个数组参数作为回调函数的参数
<?php function foobar($arg, $arg2) { echo __FUNCTION__, " got $arg and $arg2\n"; } clas ...
- MySQL查看表索引
mysql> show index from tblname; mysql> show keys from tblname; · Table 表的名称. · Non_unique 如果索引 ...
- Kettle数据同步速度调优记录
Msyql到Vertica 1.mysql中在openshop 数据库中选择其中一个300W左右数据的表 create table ip_records_tmp_01 AS SELECT * FROM ...