[SDOI2009]HH的项链 和 [HEOI2012]采花两题树状数组解法对比分析

2023-10-09 15:38

本文主要是介绍[SDOI2009]HH的项链 和 [HEOI2012]采花两题树状数组解法对比分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

https://www.luogu.com.cn/problem/P1972

  • HH的项链这个题是静态区间查询的问题,如果用树状数组来解决,那么容易想到的方法是比如说问 [ l , r ] 的 [l,r]的 [l,r]不同贝壳数量,那么我如果用树状数组维护区间的不同贝壳数,那么答案应该是 q u e r y ( r ) − q u e r y ( l − 1 ) query(r)-query(l-1) query(r)query(l1),但是这里带来一个问题,就是 [ 1 , l ] [1,l] [1,l] [ 1 , r ] [1,r] [1,r]这两个区间里面不能有重复的贝壳,否则就会出错,那如何来解决呢?
  • 一个办法就是记录当前贝壳的上一次出现的位置,如果当前贝壳不是第一次出现,那么把它上一次出现的位置所对应的树状数组的值 − 1 -1 1,这次出现的位置所对应的树状数组的值 + 1 +1 +1,但这同样存在一个问题,如果你询问右端点在上一个出现位置前面怎么办?所以我们要先把查询时候的右端点按照从小到大的顺序排个序,然后就可以进行上述操作了,每次查询完毕就记录答案
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <map>
#include <unordered_map>
using namespace std;
typedef long long ll;
const int MAXN = 2e6 + 100;
const int INF = 0x3f3f3f3f;
int Data[MAXN];
int a[MAXN];
int n, m;
struct st{int l, r;int id;bool operator< (st &x)const {return r < x.r;}
}s[MAXN];
int lowbit(int x){return x & -x;
}
void ADD(int x, int val){while(x <= n){Data[x] += val;x += lowbit(x);}
}
int query(int x){int res = 0;while(x > 0){res += Data[x];x -= lowbit(x);}return res;
}
int last[MAXN], pre[MAXN];
int ans[MAXN];
int main(){#ifdef LOCALfreopen("input.txt", "r", stdin);freopen("output.txt", "w", stdout);#endifios::sync_with_stdio(false);cin >> n;for(int i=1;i<=n;i++){cin >> a[i];pre[i] = last[a[i]];last[a[i]] = i;}cin >> m;for(int i=1;i<=m;i++){cin >> s[i].l >> s[i].r;s[i].id = i;}sort(s + 1, s + 1 + m);int now = 1;for(int i=1;i<=m;i++){while(now <= s[i].r){if(pre[now]){ADD(pre[now], -1);}ADD(now, 1);++now;}ans[s[i].id] = query(s[i].r) - query(s[i].l - 1);}for(int i=1;i<=m;i++){cout << ans[i] << '\n';}return 0;
}

https://www.luogu.com.cn/problem/P4113

  • 这个题问的也是种类数,也是静态区间查询问题,查询区间之间也是独立的,但是和上一个题的区别是必须有两个以上的同种颜色的花才能算数,这样的话我们可以再记录一个前驱的前驱,查询的时候先让前驱所对应的树状数组的值 + 1 +1 +1,前驱的前驱所对应树状数组的值 − 1 -1 1,当然前驱和前驱的前驱必须存在才能做相关操作
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <map>
#include <unordered_map>
using namespace std;
typedef long long ll;
const int MAXN = 2e6 + 100;
const int INF = 0x3f3f3f3f;
int Data[MAXN];
int a[MAXN];
int n, c, m;
struct st{int l, r;int id;bool operator< (st &x)const {return r < x.r;}
}s[MAXN];
int lowbit(int x){return x & -x;
}
void ADD(int x, int val){while(x <= n){Data[x] += val;x += lowbit(x);}
}
int query(int x){int res = 0;while(x > 0){res += Data[x];x -= lowbit(x);}return res;
}
int last[MAXN], pre[MAXN], prepre[MAXN];
int ans[MAXN];
int main(){#ifdef LOCALfreopen("input.txt", "r", stdin);freopen("output.txt", "w", stdout);#endifios::sync_with_stdio(false);cin >> n >> c >> m;for(int i=1;i<=n;i++){cin >> a[i];pre[i] = last[a[i]];last[a[i]] = i;prepre[i] = pre[pre[i]];}for(int i=1;i<=m;i++){cin >> s[i].l >> s[i].r;s[i].id = i;}sort(s + 1, s + 1 + m);int now = 1;for(int i=1;i<=m;i++){while(now <= s[i].r){if(pre[now]){ADD(pre[now], 1);}if(prepre[now]){ADD(prepre[now], -1);}++now;}ans[s[i].id] = query(s[i].r) - query(s[i].l - 1);}for(int i=1;i<=m;i++){cout << ans[i] << '\n';}return 0;
}

这篇关于[SDOI2009]HH的项链 和 [HEOI2012]采花两题树状数组解法对比分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/173844

相关文章

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.

MySQL查询JSON数组字段包含特定字符串的方法

《MySQL查询JSON数组字段包含特定字符串的方法》在MySQL数据库中,当某个字段存储的是JSON数组,需要查询数组中包含特定字符串的记录时传统的LIKE语句无法直接使用,下面小编就为大家介绍两种... 目录问题背景解决方案对比1. 精确匹配方案(推荐)2. 模糊匹配方案参数化查询示例使用场景建议性能优

关于集合与数组转换实现方法

《关于集合与数组转换实现方法》:本文主要介绍关于集合与数组转换实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Arrays.asList()1.1、方法作用1.2、内部实现1.3、修改元素的影响1.4、注意事项2、list.toArray()2.1、方

MySQL中的表连接原理分析

《MySQL中的表连接原理分析》:本文主要介绍MySQL中的表连接原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、环境3、表连接原理【1】驱动表和被驱动表【2】内连接【3】外连接【4编程】嵌套循环连接【5】join buffer4、总结1、背景

python中Hash使用场景分析

《python中Hash使用场景分析》Python的hash()函数用于获取对象哈希值,常用于字典和集合,不可变类型可哈希,可变类型不可,常见算法包括除法、乘法、平方取中和随机数哈希,各有优缺点,需根... 目录python中的 Hash除法哈希算法乘法哈希算法平方取中法随机数哈希算法小结在Python中,

Java Stream的distinct去重原理分析

《JavaStream的distinct去重原理分析》Javastream中的distinct方法用于去除流中的重复元素,它返回一个包含过滤后唯一元素的新流,该方法会根据元素的hashcode和eq... 目录一、distinct 的基础用法与核心特性二、distinct 的底层实现原理1. 顺序流中的去重

关于MyISAM和InnoDB对比分析

《关于MyISAM和InnoDB对比分析》:本文主要介绍关于MyISAM和InnoDB对比分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录开篇:从交通规则看存储引擎选择理解存储引擎的基本概念技术原理对比1. 事务支持:ACID的守护者2. 锁机制:并发控制的艺

CSS中的Static、Relative、Absolute、Fixed、Sticky的应用与详细对比

《CSS中的Static、Relative、Absolute、Fixed、Sticky的应用与详细对比》CSS中的position属性用于控制元素的定位方式,不同的定位方式会影响元素在页面中的布... css 中的 position 属性用于控制元素的定位方式,不同的定位方式会影响元素在页面中的布局和层叠关

MyBatis Plus 中 update_time 字段自动填充失效的原因分析及解决方案(最新整理)

《MyBatisPlus中update_time字段自动填充失效的原因分析及解决方案(最新整理)》在使用MyBatisPlus时,通常我们会在数据库表中设置create_time和update... 目录前言一、问题现象二、原因分析三、总结:常见原因与解决方法对照表四、推荐写法前言在使用 MyBATis

Python主动抛出异常的各种用法和场景分析

《Python主动抛出异常的各种用法和场景分析》在Python中,我们不仅可以捕获和处理异常,还可以主动抛出异常,也就是以类的方式自定义错误的类型和提示信息,这在编程中非常有用,下面我将详细解释主动抛... 目录一、为什么要主动抛出异常?二、基本语法:raise关键字基本示例三、raise的多种用法1. 抛