后缀数组 模板(结构体) DC3 与倍增

2023-11-19

DC3

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M = 1e6+7;

struct suffix_array{
    int str[M],sa[M],rank[M],t1[M],t2[M],c[M];
    //int lg2[M];int rmq[21][M],height[M];
    //sa[i],排名i(1-n)后缀的起始下标(0 - n-1)
    //rank[i],下标i(0 - n-1)后缀的排名(1 - n) 
    bool cmp(int *r,int a,int b,int l){
        return r[a]==r[b]&&r[a+l]==r[b+l];
    }
    void gao(int n,int m){
    	str[n]=0;
        n++; int i, j, p, *x = t1, *y = t2;
        for(i=0;i<m;++i) c[i]=0;
        for(i=0;i<n;++i) c[x[i]=str[i]]++;
        for(i=1;i<m;++i) c[i]+=c[i-1];
        for(i=n-1;i>=0;--i) sa[--c[x[i]]]=i;
        for(j=1;j<n;j<<=1){
            p=0;
            for(i=n-j;i<n;++i) y[p++]=i;
            for(i=0;i<n;++i) if(sa[i]>=j) y[p++]=sa[i]-j;

            for(i=0;i<m;++i) c[i]=0;
            for(i=0;i<n;++i) c[x[y[i]]]++;
            for(i=1;i<m;++i) c[i]+=c[i-1];
            for(i=n-1;i>=0;--i) sa[--c[x[y[i]]]]=y[i];

            swap(x,y); p=1; x[sa[0]]=0;
            for(i=1;i<n;++i) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
            if(p>=n) break; m=p;
        }
        int k=0; n--;
        for(i=0;i<=n;++i) rank[sa[i]]=i;
        for(i=0;i<n;++i){
            if(k) k--;
            j=sa[rank[i]-1];
            while(str[i+k]==str[j+k]) ++k;
            //height[rank[i]]=k;
        }
    }
    /*void initlcp(int n){
    	lg2[0]=-1;for(int i=1;i<N;++i) lg2[i]=(i&(i-1))?lg2[i-1]:lg2[i-1]+1;
        for(int i=1;i<=n;++i)
            rmq[0][i]=height[i];
        for(int k=1;k<=lg2[n];++k)
            for(int i=1;i+(1<<k)-1<=n;++i)
                rmq[k][i]=min(rmq[k-1][i],rmq[k-1][i+(1<<(k-1))]);
    }
    int lcp(int a,int b){
        a=rank[a]; b=rank[b];
        if(a>b) swap(a,b); a+=1;
        int d=lg2[b-a+1];
        return min(rmq[d][a],rmq[d][b-(1<<d)+1]);
    }*/
}sa;
char s[M];
int B[M];
int main()
{
	cin>>s;
	int n =strlen(s);
	for(int i=0;i<n;i++)sa.str[i]=s[i]-'\0'+1;
	sa.gao(n,260);
	for(int i=1;i<=n;i++)printf("%d ",sa.sa[i]+1);
	puts("");
	return 0;
}

倍增

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M = 1e6+7;

struct SA{
    int sa[M],c[M],Rank[M],t1[M],t2[M];
    //rak[i]  下标i的后缀的排名
	//sa[i]    排名i (从0到n-1)的后缀的下标
	//待排序的字符串放在 s 数组中,从 s[0]到 s[n-1],长度为 n,且最大值小于 m。 
	//约定除 s[n-1]外所有的 s[i]都大于 0, s[n-1]=0。函数结束后,结果放在 sa 数组中,从 sa[0]到 sa[n-1]。
    void Debug(int n,int m) 
	{
	    printf("*****************\n");
	    printf("下标"); for (int i = 0; i < n; i++) printf("%d ", i);     printf("\n");
	    printf("sa  "); for (int i = 0; i < n; i++) printf("%d ", sa[i]); printf("\n");
	    printf("c "); for (int i = 0; i < m; i++) printf("%d ", c[i]); printf("\n");
	    printf("x  "); for (int i = 0; i < n; i++) printf("%d ", t1[i]); printf("\n");
	    printf("y  "); for (int i = 0; i < n; i++) printf("%d ", t2[i]); printf("\n");
	}
	void gao(int* s,int n,int m)//字符集,字符集大小,字符集范围 
	{
        s[n]=0;
        int* x=t1,*y=t2;
        for(int i=0;i<m;i++) c[i]=0;//基数排序,数值i的桶里元素个数 
        for(int i=0;i<n;i++) c[x[i]=s[i]]++;
        for(int i=1;i<m;i++) c[i]+=c[i - 1] ;//基数排序,数值i的桶里元素的排名最大值 
        for(int i=n-1; i >= 0; i--) sa[--c[x[i]]]=i;
      //  Debug(n,m);
         //这里 x 数组保存的值相当于是 rank 值,下标i的排名(有重复)。下面的操作只是用 x 数组来比较字符的大小,所以没有必要求出当前真实的 rank 值
        for(int k=1;k<=n;k<<=1)
		{
            int p=0 ;//y数组保存的是,按第二关键字排序后的数组下标 
            for(int i=n-k;i<n;i++) y[p++]=i ;//这些位置无后k个,即第二关键字在前 
            for(int i=0;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k;//利用上次基数排序的第一关键字当这次的第二关键字 
            for(int i=0;i<m;i++) c[i]=0;
            for(int i=0;i<n;i++) c[x[y[i]]]++;
            for(int i=1;i<m;i++) c[i]+=c[i-1];
            for(int i=n-1;i>= 0; i--) sa[--c[x[y[i]]]]=y[i];//基数排序 
    //        Debug(n,m);
            swap(x,y);p =1;x[sa[0]]=0;
            for(int i=1;i<n;i++)
                x[sa[i]]=(y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k])?p-1:p++;
            if(p>=n)break ;
            m=p;
        }
        for(int i=0;i<n;i++)Rank[sa[i]]=i;
       // Debug(n,m);
    }
}suf;
char s[M];
int B[M];
int main()
{
	cin>>s;
	int n =strlen(s);
	for(int i=0;i<n;i++)B[i]=s[i]-'\0'+1;
	suf.gao(B,n,260);
	for(int i=0;i<n;i++)printf("%d ",suf.sa[i]+1);
	puts("");
	return 0;
}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

后缀数组 模板(结构体) DC3 与倍增 的相关文章

  • 贝叶斯优化及其python实现

    贝叶斯优化是机器学习中一种常用的优化技术 其目的是在有限步数内寻找函数的最大值或最小值 它可以被视为在探索不同参数配置与观察这些配置结果之间寻求平衡点的过程 基本思想是将我们在过去的观察和体验 传递到下一个尝试中 从而在等待数据的反馈时 逐
  • 微信小程序开发实战第五讲之授权登录

    上一节 我们实现了简单的通过用户名和密码调用接口进行登录的实战 但是在小程序中 有个特殊的情况 就是很少有厂商去开发一个注册功能或者是通过用户名 密码来登录的逻辑 为什么 因为APP 小程序为了用户体验 是尽量多的避免用户多次输入交互 所以
  • 物联网LoRa系列-17:LoRa终端Sx1262芯片内部的射频信号放大器

    至此 我们已经拆解了天线是如何发送和接收空中的无线电磁波信号 拆解了无线终端如何对射频前端的高频电信号进行进一步处理的 还拆解了无线终端的发送和接收如何分时复用天线的半双工模式 本篇将进一步拆解无线终端是如何对射频电信号进行进一步的处理 包
  • 【优化器】(一) SGD原理 & pytorch代码解析

    1 简介 很多情况下 我们调用优化器的时候都不清楚里面的原理和构造 主要基于自己数据集和模型的特点 然后再根据别人的经验来选择或者尝试优化器 下面分别对SGD的原理 pytorch代码进行介绍和解析 2 梯度下降 梯度下降方法可以分为3种
  • constexpr 用法

    1 简介 constexpr函数指的是在编译的时候就能得到其返回值的函数 也就是说编译器将constexpr函数直接转换成其返回值 因此 constexpr函数都是被隐式地定义为内联函数 使用constexpr关键字来修饰constexpr
  • C++设计模式(二)观察者模式

    1 观察者模式知识点 1 定义 定义对象间的一种一对多的依赖关系 当一个对象的状态发生改变的时候 所有依赖它的对象都得到通知并自动更新 2 动机 将一个系统分割成一系列相互协作的类有一个常见的副作用 需要维护相关对象间的一致性 我们不希望为
  • 设计模式——原型模式

    原型模式顾名思义 就是指以某个实例为原型 copy出一个新的实例 该实例属性与原型相同或者是类似 很多时候 我们需要创建大量的相同或者相似的对象 如果一个个用new 构造函数的形式去创建的话比较繁琐 就像孙悟空要想变出成千上万个猴子猴孙总不
  • wmic命令学习

    我目前知道wmic可以查询进程 还可以查询服务 查询进程使用wmic process 如果想知道进程的名字 进程号 执行文件路径可以通过get来获取 还可以根据where筛选进程进行查询 wmic process get name proc
  • 开心档-软件开发入门教程网之Bootstrap4 信息提示框

    Bootstrap4 信息提示框 Bootstrap 4 可以很容易实现信息提示框 提示框可以使用 alert 类 后面加上 alert success alert info alert warning alert danger alert
  • Struts2 校验(XML配置校验)

    参考文档 http struts apache org 2 0 9 docs ajax client side validation html http struts apache org 2 0 9 docs pure javascrip
  • 基础篇-常用对称、非对称、摘要加密算法介绍

    本文属于 OpenSSL加密算法库使用系列教程 之一 欢迎查看其它文章 也可以查看 GmSSL国密加密算法库使用系列教程 常见的加密算法可以分成三类 对称加密算法 非对称加密算法 Hash算法 一 对称加密算法 对称加密是使用同一个密钥对信
  • springMVC基于Session实现动态国际化

    1 在spring配置文件中配置资源文件properties的位置及公共名 下列配置指定的properties文件处于src目录下的resources文件夹中 名字为message info properties
  • Unity 反射绑定UI

    ui的名称和定义的字段名要保持一致 using System using System Collections using System Collections Generic using System Linq using System
  • 计算机f g 盘找不到了,电脑E/F盘符突然不见了怎么办

    随着分区工具的普及 越来越多的人起初自己对硬盘重新界定分区 由于目前这些分区软件和平台不兼容造成再次分区的之后 分区会重叠 这会导致以后使用电脑的之后 会时常丢失一个或几个分区 1 首先开启磁盘管理 打开的步骤 右击桌面的计算机界面 管理
  • Compiler- volatile关键字

    为了直观的感受编译器为程序所做的编译优化 我们通过以下的C 程序来进行演示 只能体现编译优化的一小部分hh 请大家预测一下下面代码的输出结果 include
  • didChangeDependencies什么时候被调用

    参考 我先上一个Demo 这个Demo也就是网上面传的比较广的 我们就以这个来举例子说明网上的结论 父级结构中的层级发生变化时didChangeDependencies被调用 这个结论为什么是不完整 import package flutt
  • (2022 COLING)Context-Tuning情景化提示

    论文题目 Title Context Tuning Learning Contextualized Prompts for Natural Language Generation 研究问题 Question 自然语言生成 生成长文本 研究动
  • 5G+边缘计算,对于VR移动电竞游戏来说意味着什么?

    这是一个5G 边缘计算意义的问题 其实对VR游戏 特别是电竞游戏 这类大流量 低延迟的应用服务来说 大多数人第一时间想到的优点会是高达1Gbps s的数据传输速度 虽然事实确实如此 但并不是全部 从技术上讲 无线传输性能的进步能给我们带来更
  • element 可移动dialog

    import Vue from vue v dialogDrag 弹窗拖拽属性 Vue directive dialogDrag bind el binding vnode oldVnode const dialogHeaderEl el

随机推荐

  • ES6数组方法总结

    1 forEach let array 1 2 3 4 array forEach item index array gt console log item forEach会遍历数组 没有返回值 不允许在循环体内写return 不会改变原来
  • 小程序自定义导航栏返回主页

    小程序自定义导航栏返回主页 效果图 在app js中获取状态栏的高度statusBarHeight 自定义组件navbar wxml 自定义组件navbar wxss 自定义组件navbar json 自定义组件navbar js 调用组件
  • 睿智的目标检测60——Tensorflow2 Focal loss详解与在YoloV4当中的实现

    睿智的目标检测60 Tensorflow2 Focal loss详解与在YoloV4当中的实现 学习前言 什么是Focal Loss 一 控制正负样本的权重 二 控制容易分类和难分类样本的权重 三 两种权重控制方法合并 实现方式 学习前言
  • 如何用Stata完成(shui)一篇经济学论文(九):画线性图

    目录 普通线性图 多图并列 一图多线 什么 为什么只讲线形图 因为我只用过线形图 言归正传 我的确只用过线形图 说了跟没说一样 Stata画图给我的感觉一直都是很复杂 很多命令 我觉得好像也没有很多的地方要画图 一般就画个线形图看看趋势 如
  • 2023年,想要年赚百万必懂的道理?

    1 一个人只有经历过风雨沧桑 才会明白一个道理 这个世界最大的监狱就是人的思维 而越狱最好的方式就是人的觉醒 2 人活明白了就会知道 不要拿自己去跟别人比较 后果不是忘记了自己 就是让自己失落 3 如果一个人不向内求 总是拿自己的一点优势去
  • 机器学习可解释性

    20210508 随笔 后续有时间在对概念有了深入理解之后再进行整理 0 引言 今天不想写论文 就想起了之前关注的一个内容 机器学习的可解释性 在之前的时候 或多或少了解这个东西 发现他更多的是从特征的角度来解释 这个特征怎么影响了模型 但
  • python实现货币转换

    实现美元与人民币的转换 2022 4 16 1美元 6 37人民币 moneyStr input 请输入带有标志 RMB rmb USD usd 的钱数 if moneyStr 3 in RMB rmb dollar eval moneyS
  • [java]线程安全问题

    线程安全问题产生有五个产生原因 1 线程的随机调度和抢占式执行 就是这个机制使得线程安全问题产生 2 代码结构 多个线程对同一个变量进行修改 3 原子性 修改操作的是可拆分的 导致脏读问题 4 内存可见性问题 一个线程读一个线程写 5 指令
  • 自定义屏幕保护

    一 设计器页面及代码 Form2 Designer cs namespace 自定义屏保 partial class Form2
  • 直接执行:sudo su 就可以了。

    直接执行 sudo su 就可以了
  • GD32F405RGT6定时器固件库(所有定时器的配置(12个))

    GD32F405RGT6所有定时器的配置 GD32F4XXX系列拥有12个定时器 定时器的类型如下表 一般我们可以根据定时器的作用以及类型选取合适的定时器 在这次对GD的单片机而言我就将它所拥有的12个定时器撸了一遍 通用定时器以及高级定时
  • 虚拟ip、浮动ip

    虚拟ip 虚拟 IP 是一个虚拟的 软件定义的 IP 地址 它可以用来在网络中隐藏真实的 IP 地址 或者在多个物理服务器之间共享一个 IP 地址 虚拟 IP 通常用于网络负载均衡 高可用性和网络安全等方面 Docker 在Docker中
  • Golang在ARM/Linux平台上函数参数的传递

    一 前言 作为一名初级的嵌入式软件开发从业者 工作中大部分项目以C语言实现 使用C语言来编写代码 通常我们可以预测到编译生成的汇编 机器编码的大致情况 在不同的芯片架构上 有其相应的ABI标准 而近年来逐渐流行起来的Go语言编程 虽然同样语
  • java使用线程池批量插入mysql数据

    首先我们使用最原始的for循环插入数据 for int i 0 i lt 100000000 i service add new LongTest setStatus 1 setName NumberUtil getPwdRandom 5
  • [python爬虫] Selenium常见元素定位方法和操作的学习介绍

    这篇文章主要Selenium Python自动测试或爬虫中的常见定位方法 鼠标操作 键盘操作介绍 希望该篇基础性文章对你有所帮助 如果有错误或不足之处 请海涵 前文目录 Python爬虫 在Windows下安装PhantomJS和Caspe
  • 如何选择适合自己的STM32 微控制器?

    选择控制器型号 俗称选型 首先要搞清楚芯片型号各类参数所表示的含义 STM32 顾名思义 ST表示意法半导体 M Microelectronics的缩写 表示微控制器 32 32位的意思 表示这是一个32位的微处理器芯片 STM32自带了各
  • Java集合总结

    Java常用集合总结 集合的整体框架 Collection的上层是Iterable接口 意味着Collection所有的子类都可以使用迭代器去访问元素 Collection还分为Set和List接口 Set接口下的实现子类都是不允许存在重复
  • 用java写一个定时任务,设定某一时间点触发

    可以使用 Java 的 java util Timer 类来创建定时任务 首先 需要创建一个 TimerTask 对象 它代表要在指定的时间点执行的任务 为了实现定时任务的逻辑 需要在 TimerTask 类的子类中重写 run 方法 然后
  • 【HTML】2023跨年烟花代码

    2022年圣诞节到来啦 很高兴这次我们又能一起度过 文章目录 前言 效果展示 一 夜景烟花绽放动画效果 HTML源码 2023年 新年 春节倒计时代码 源码 2023除夕倒计时 效果展示 源码 宇宙星空 效果展示 1 源码 2 思路 3 步
  • 后缀数组 模板(结构体) DC3 与倍增

    DC3 include