[其他ST产品] 数据结构之ST表

[复制链接]
785|15
 楼主| 个百zz分点个 发表于 2023-4-21 23:36 | 显示全部楼层 |阅读模式
个人理解与概括
ST表就是利用倍增思想,预处理出所有长度为2j的区间的某个需要维护的值。由于任意区间都可被分为两个重复的2j长度的区间,ST表可以O(1)的查询某些值。
可以维护啥值???
由于两个区间有重复的部分,重复部分被计算了两次。对于可重复贡献的值,不影响,比如最值,gcd,位或,位与。因为当重复部分被多次计算的时候,这些值都不会受到影响,而对于区间和这种不可重复贡献的值时,会受影响。
————————————————
版权声明:本文为CSDN博主「是哆啦D梦」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43602607/article/details/108503927

 楼主| 个百zz分点个 发表于 2023-4-21 23:36 | 显示全部楼层
算法分析
模板题链接

下面以求区间最大值来学习一下ST表
利用倍增思想:我们设 f[i][j] 为从第i个结点开始的连续2j个点的最值,即 f[i][j] 是第i个点到第i+2j-1个点的最值。我们先求小区间再求大区间
很显然有 f[i][j] = max(f[i][j-1],f[i+2j][j-1]。通过这个递推式子预处理出整个 f 数组
给定一个查询 [l,r],假设为 [1,10] ,其可变成求 [1,8] 和 [3,10] 两个区间的最值,由于两个区间都在预处理的时候都算完了,我们可以直接O(1)的查。
 楼主| 个百zz分点个 发表于 2023-4-21 23:36 | 显示全部楼层
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N=1e5;
  4. int a[N],n,f[N][30],Log2[N];
  5. //f[i][p]表示从第i个点开始的2^p个数的最值
  6. //即区间   [i,i+2^p-1]  的最值

  7. void init() {//nlogn预处理
  8.         for(int i=1; i<=n; i++)f[i][0]=a[i];//f[i][0]为本身
  9.         for(int p=1; (1<<p)<=n; p++) {//防出界
  10.                 for(int i=1; i+(1<<p)-1<=n; i++) {//第i个点控制的区间到1+(1<<p)-1,防出界
  11.                         f[i][p]=max(f[i][p-1],f[i+(1<<(p-1))][p-1]);
  12.                         //f[i][p]的最值由前半段f[i][p-1]和后半段f[i+pow(2,p-1)][p-1]得来
  13.                 }
  14.         }
  15.     int t=0;//log2打表
  16.         for(int i=0;i<=n;i++){
  17.             while((1<<(t+1))<=i)t++;
  18.             Log2[i]=t;
  19.         }
  20. }
  21. int query(int l,int r){
  22.         int k=Log2[r-l+1];
  23.         return max(f[l][k],f[r-(1<<k)+1][k]);
  24. }
  25. int main(){
  26.         int m,l,r;
  27.         cin>>n>>m;
  28.         for(int i=1;i<=n;i++)scanf("%d",&a[i]);
  29.         init();
  30.         for(int i=1;i<=m;i++){
  31.                 scanf("%d%d",&l,&r);
  32.                 printf("%d",query(l,r));
  33.         }
  34.         return 0;
  35. }

 楼主| 个百zz分点个 发表于 2023-4-21 23:36 | 显示全部楼层
求区间gcd只需要把max换成gcd就可
求位或和位与只需要把max换成中间加一个&|即可
Wordsworth 发表于 2024-6-6 07:05 | 显示全部楼层

主从定时的方式占用CPU资源少
Clyde011 发表于 2024-6-6 08:08 | 显示全部楼层
Clyde011 发表于 2024-6-6 08:08 | 显示全部楼层

主从定时器门控的方式
公羊子丹 发表于 2024-6-6 09:01 | 显示全部楼层

主定时器为TIM1,通道2配置为PWM输出
万图 发表于 2024-6-6 10:04 | 显示全部楼层

中断计数的方式实现简
Uriah 发表于 2024-6-6 11:07 | 显示全部楼层

当PWM频率较高时,频繁的中断将影响程序运行的效率
帛灿灿 发表于 2024-6-6 13:03 | 显示全部楼层

都可以产生指定个数的PWM脉冲
Bblythe 发表于 2024-6-6 14:06 | 显示全部楼层

输出了5个频率为10KHz的PWM脉冲
周半梅 发表于 2024-6-6 16:02 | 显示全部楼层

从定时器为TIM2,从模式选择为门控模式,触发源选择ITR0,开启定时器2中断。
Pulitzer 发表于 2024-6-6 17:05 | 显示全部楼层

根据实际需求选择用哪种方式
童雨竹 发表于 2024-6-6 19:01 | 显示全部楼层

使能主从模式,触发事件选择为更新事件,不需要开启中断。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

53

主题

679

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部