洛谷 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]$ 为例,求解区间 ...
随机推荐
- Page.IsPostBack
ASP.NET页面的执行顺序说明:Page_Init(页面初始化引发的事件)——Page_Load(加载页面时引发的事件)——ControlEvent(服务器控件引发的事件)——Page_UnLoad ...
- JVM(4)之 使用MAT排查堆溢出
开发十年,就只剩下这套架构体系了! >>> 接下来讲解如何设置以及当发生堆溢出的时候怎么排查问题.先看一小段代码: 代码中使用了一个无限循环来为list添加对象,如果采用 ...
- mpvue 无法获取$store的问题
在开发的时候,我们喜欢将一些公共的方法,属性,放在一个特定的位置,例如在mpvue开发小程序的时候, 我们将其放在 vue提供的store里面,或者在mainjs中通过Vue.prototype.xx ...
- XMPP即时通讯协议使用(十三)——获取当前在线用户或关闭指定用户
1.开启REST API插件或根据需求修改其插件源码: 2.添加服务器->服务器管理->系统属性中添加 plugin.restapi.enabled=true 3.pom依赖 <de ...
- elasticsearch 基础 —— Inner hits
Inner hits The parent-join and nested 功能允许返回具有不同范围匹配的文档.在父/子案例中,基于子文档中的匹配返回父文档,或者基于父文档中的匹配返回子文档.在嵌套的 ...
- 负载均衡算法WeightedRoundRobin(加权轮询)简介及算法实现
Nginx的负载均衡默认算法是加权轮询算法,本文简单介绍算法的逻辑,并给出算法的Java实现版本. 本文参考了Nginx的负载均衡 - 加权轮询 (Weighted Round Robin). ...
- vue,一路走来(7)--响应路由参数的变化
今天描述的问题估计会有很多人也遇到过. vue-router多个路由地址绑定一个组件造成created不执行 也就是文档描述的,如下图 我的解决方案: created () { console.log ...
- [IOI1998]Polygon(区间dp)
[IOI1998]Polygon 题意翻译 多边形是一个玩家在一个有n个顶点的多边形上的游戏,如图所示,其中n=4.每个顶点用整数标记,每个边用符号+(加)或符号*(乘积)标记. 第一步,删除其中一条 ...
- js中的回钓函数,C#中的委托
$(function(){ myfunction(sayHi); }); var sayHi=function(){ alter('你好'); } function myfunction(a){ a( ...
- 查完数据库order_by后跟[:9]切片取前9位的值