uva12206 - Stammering Aliens 哈希LCP和后缀数组两种做法

7系列ZYNQ硬件调试:Vitis无法识别ARM DAP的排查与解决 本文详细分析了Xilinx 7系列ZYNQ芯片在Vitis开发环境中无法识别ARM DAP的常见问题及解决方案。从硬件设计检查(电源系统、时钟电路)、JTAG连接诊断到软件环境排查,提供了全面的调试指南。特别针对ARM DAP初始化失败的情况,给出了实用的排查步骤和预防措施,帮助开发者快速定位和解决类似问题。 阅读详情

Dr. Ellie Arroway has established contact with an extraterrestrialcivilization. However, all efforts to decode their messages have failed so farbecause, as luck would have it, they have stumbled upon a race of stutteringaliens! Her team has found out that, in every long enough message, the mostimportant words appear repeated a certain number of times as a sequence ofconsecutive characters, even in the middle of other words. Furthermore,sometimes they use contractions in an obscure manner. For example, if theyneed to say bab twice, they might just send the messagebabab, which hasbeen abbreviated because the secondb of the first word can be reused as thefirst b of the second one.

Thus, the message contains possibly overlapping repetitions of the same wordsover and over again. As a result, Ellie turns to you, S.R. Hadden, for help inidentifying the gist of the message.

Given an integer m, and a string s, representing the message, your task isto find the longest substring ofs that appears at least m times. Forexample, in the messagebaaaababababbababbab, the length-5 wordbabab iscontained 3 times, namely at positions5, 7 and 12 (where indices startat zero). No substring appearing3 or more times is longer (see the firstexample from the sample input). On the other hand, no substring appears11times or more (see example 2).

In case there are several solutions, the substring with the rightmostoccurrence is preferred (see example3).

Input 

The input contains several test cases. Each test case consists of aline with an integerm (m$ \ge$1), the minimum number of repetitions,followed by a line containing a string s of length between m and 40 000,inclusive. All characters ins are lowercase characters from ``a'' to ``z''.The last test case is denoted bym = 0 and must not be processed.

Output 

Print one line of output for each test case. If there is no solution, outputnone; otherwise, print two integers in a line, separated by a space.The first integer denotes the maximum length of a substring appearing at leastm times; the second integer gives the rightmost possible starting position of such asubstring.

Sample Input 

3
baaaababababbababbab
11
baaaababababbababbab
3
cccccc
0

Sample Output 

5 12
none
4 2

  给一个串,找出至少出现m次的最长子串,如果存在多个,输出最后那个串的位置。

  基于HASH值的LCP算法:为每个后缀计算一个HASH值,任取x,H[i]=H[i+1]x+s[i](0<=i<n,H[n]=0)。H[i]=s[n-1]*x^(n-1-i)+s[n-2]*x(n-2-i)+...+s[i+1]*x+s[i]。HASH(i,L)=H(i)-H(i+L)*x^L。因此HASH(i,L)=s[i+L-1]*x^(L-1)+s[i+L-2]*x(L-2)+...+s[i+1]*x+s[i]。这样就构造出一个s[i]~s[i+L-1]和L有关的字符串HASH值,用unsigned long long,自然溢出,相当于取模2^64。可能会冲突,但概率很小。

  那么用HASH做这个题只需要二分串的长度L,对所有长度为L的串按HASH值排序,HASH相等的时候按串的位置排,位置靠后的排后面,这样HASH值相等的串也就是同样的串都排到一起了,如果大于等于M个,就更新最后位置。复杂度O(logN*logN*N)。


  用后缀数组做的话复杂度是O(logN*N)。构造完后缀数组和height后,也是分组的思想,二分串的长度L,同一组的公共前缀长度大于等于L(但如果一组只有一个后缀的时候不一定满足长度大于等于L)。最后再根据而分出的L求最后位置,特别要注意的是当R-L==1的时候不一定满足长度大于等于L,所以还要判一下。在满足R-L>=M的时候更新最后位置就行。


HASH:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<utility>
#include<cstring>
#include<stack>
#include<queue>
#include<map>
#include<deque>
#include<cmath>
#include<map>
#define INF 0x3f3f3f3f
#define eps 1e-3
using namespace std;
typedef long long LL;
const int MAXN=40010;
const int x=123;
int M,n;
char str[MAXN];
int rank[MAXN];
unsigned long long H[MAXN],xp[MAXN],hash[MAXN];
void hash_init(){
    H[n]=0;
    for(int i=n-1;i>=0;i--) H[i]=H[i+1]*x+str[i]-'a';
    xp[0]=1;
    for(int i=1;i<=n;i++) xp[i]=xp[i-1]*x;
}
bool cmp(const int& a,const int& b){
    return hash[a]<hash[b]||(hash[a]==hash[b]&&a<b);
}
int possible(int L){
    int cnt,pos=-1;
    for(int i=0;i<n-L+1;i++){
        rank[i]=i;
        hash[i]=H[i]-H[i+L]*xp[L];
    }
    sort(rank,rank+n-L+1,cmp);
    for(int i=0;i<n-L+1;i++){
        if(i==0||hash[rank[i]]!=hash[rank[i-1]]) cnt=0;
        if(++cnt>=M) pos=max(pos,rank[i]);
    }
    return pos;
}
int main(){
    freopen("in.txt","r",stdin);
    while(scanf("%d",&M)!=EOF&&M){
        scanf("%s",str);
        n=strlen(str);
        hash_init();
        if(possible(1)==-1){
            printf("none\n");
            continue;
        }
        int L=1,R=n+1;
        while(L+1<R){
            int mid=L+(R-L)/2;
            if(possible(mid)!=-1) L=mid;
            else R=mid;
        }
        int pos=possible(L);
        printf("%d %d\n",L,pos);
    }
    return 0;
}

后缀数组:

#include<iostream>
#include<queue>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<algorithm>
#define INF 0x3f3f3f3f
#define eps 1e-9
#define MAXNODE 105
#define MOD 10000007
#define SIGMA_SIZE 4
typedef long long LL;
using namespace std;

const int MAXN=40010;
const int MAXM=110;

int M,ans,pos;
char str[MAXN];

struct SuffixArray{
    int s[MAXN];
    int sa[MAXN];
    int rank[MAXN];
    int height[MAXN];
    int c[MAXN];
    int t[MAXN],t2[MAXN];
    int n;

    void clear(){
        n=0;
        memset(sa,0,sizeof(sa));
    }

    void build_sa(int m){
        int i,*x=t,*y=t2;
        for(i=0;i<m;i++) c[i]=0;
        for(int i=0;i<n;i++) c[x[i]=s[i]]++;
        for(int i=1;i<m;i++) c[i]+=c[i-1];
        for(int i=n-1;i>=0;i--) sa[--c[x[i]]]=i;
        for(int k=1;k<=n;k<<=1){
            int p=0;
            for(int i=n-k;i<n;i++) y[p++]=i;
            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];
            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;
        }
    }

    void build_height(){
        int k=0;
        for(int i=0;i<n;i++) rank[sa[i]]=i;
        height[0]=0;
        for(int i=0;i<n-1;i++){
            if(k) k--;
            int j=sa[rank[i]-1];
            while(s[i+k]==s[j+k]) k++;
            height[rank[i]]=k;
        }
    }
}sa;

bool possible(int len){
    int L=1;
    for(int R=2;R<=sa.n;R++) if(R==sa.n||sa.height[R]<len){
        if(R-L>=M) return true;
        L=R;
    }
    return false;
}

int calp(){
    int L=1,ret=0,maxp=0,MIN=INF;
    for(int R=2;R<=sa.n;R++){
        maxp=max(maxp,sa.sa[R-1]);
        if(R==sa.n||sa.height[R]<ans){
            if(R-L==1){
                if(sa.n-sa.sa[L]-1>=ans&&R-L>=M) ret=max(ret,maxp);
            }
            else if(R-L>=M) ret=max(ret,maxp);
            maxp=0;
            MIN=INF;
            L=R;
        }
    }
    return ret;
}

bool solve(int len){
    if(!possible(1)) return false;
    int L=1,R=len+1;
    while(L+1<R){
        int mid=L+(R-L)/2;
        if(possible(mid)) L=mid;
        else R=mid;
    }
    ans=L;
    pos=calp();
    return true;
}

int main(){
    freopen("in.txt","r",stdin);
    while(scanf("%d",&M)!=EOF&&M){
        sa.clear();
        scanf("%s",str);
        int len=strlen(str);
        for(int i=0;i<len;i++) sa.s[sa.n++]=str[i]-'a'+1;
        sa.s[sa.n++]=0;
        sa.build_sa(30);
        sa.build_height();
        if(!solve(len)) printf("none\n");
        else printf("%d %d\n",ans,pos);
    }
    return 0;
}


TensorRT的安装:一步一步教会你如何安装TensorRT TensorRT(Tensor Runtime)是由NVIDIA开发的一个用于深度学习推理(inference)优化的库,它可以在NVIDIA的GPU上加速神经网络模型的推理过程,从而提高模型的性能和效率。安装完成后,需要将CUDA的安装路径添加到系统环境变量中,以便系统能够找到CUDA的库文件。根据你安装的CUDA版本,将CUDNN的库文件复制到CUDA的安装目录中。要使用TensorRT,首先需要安装NVIDIA的CUDA和cuDNN库,并根据NVIDIA官方文档安装TensorRT。 阅读详情

相关推荐

【远控使用】Cobalt Strike横向渗透域控

categories: 知识积累 top: FALSE copyright: true abbrlink: 1643719980 #date: '2021-8-7 12:00:00' #description:1400x780 tags: 内网渗透 提权 渗透测试 黑客工具photos: https://gitee.com/gylq/cloudimages/raw/master/img/image-20210826182104275.png 前言 Cobalt Strike.

孤桜懶契 2702

模板总结——基于哈希的LCP问题

问题引入 求第i位开始的后缀和第j位开始的后缀的最长公共前缀的长度? 高度数组&amp;&amp;RMQ 求出高度数组lcp,假设rank[i]小于rank[j],那么后缀i和后缀j的LCP值等于min{lcp[rank[i],lcp[rank[i+1],…lcp[rank[j]-1}. 预处理RMQ即可O(1)查询LCP值。但由于是预处理RMQ,无法动态回答LCP回答。也就是说一旦题目中...

EnjoyingAC的博客 1304

别再自己写组件了!用uni-app的midButton属性5分钟搞定中间凸起TabBar(H5/小程序通用)

本文详细介绍了uni-app官方提供的midButton属性,帮助开发者5分钟内实现中间凸起的TabBar效果,无需编写繁琐的自定义组件代码。该方案兼容H5和微信小程序平台,配置简单且维护成本低,大幅提升开发效率和性能表现。

weixin_30431445的博客 347

POJ3882 Stammering Aliens 后缀数组+二分

统计出现m次的重复字串最长的长度和最右边的一个字符串的开始位置。可重叠 很明显的后缀的公共前缀长度问题,high数组的应用。 Stammering Aliens Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 422   Accepted: 153

896

软件工程案例教程·韩万江【课后习题】

!!!!

weixin_57858263的博客 6417

【深度学习】手把手教你在远程服务器上跑 YOLOv3 相关代码(含环境配置)

这篇文章主要记录了如何配置项目环境以及如何在远程服务器上跑 YOLOv3 模型。

作者正在煮茶中... 2383

uva 12206 - Stammering Aliens(哈希)

题目链接:uva 12206 - Stammering Aliens 题目大意:给出一个字符串,找出至少出现m次的最长子串。 解题思路:哈希算法,将每个后缀数组建立一个哈希值,每次二分长度判断,每次判断时将哈希值排序,计数即可。 #include #include #include using namespace std; typedef unsigned long lon

不慌不忙、不急不躁 1444

电工识图入门:从电气符号到控制逻辑的完整指南

电工图纸是电气工程领域的通用语言,无论是设备安装、线路检修还是系统设计,看不懂图纸就像航海没有海图。很多初学者面对复杂的电气符号和线路走向感到无从下手,实际上只要掌握正确的识图方法,就能从简单的照明电路逐步过渡到复杂的自动化控制系统。 本文将从最基础的电气符号和图纸类型讲起,通过实际图纸案例解析,带你建立完整的识图逻辑。你将学会如何区分主回路和控制回路,如何追踪电流路径,以及如何结合图纸进行故障排查。无论你是电工新手、设备维护人员还是相关专业学生,这套方法都能帮你快速提升图纸理解能力。 1. 电气图纸基础:

chengyixian7877的博客 337

UVA - 12206 Stammering Aliens (hash)

这题其实很容易想到2分长度,关键是2分后,怎么判断出现最多次的串是否》=m次了。这里需要用到hash来处理。 对于一个字符串   H[i] =H[i+1]*131+s[i]  ;其中 H[n]=0;那么对于一个长度为L的串 ,hanh[i,l]=H[i]-H[i+L]*x^L ; 这样记录每个字符串的hash值,然后再处理起来就比较简单了。 VIEW CODE #include #includ

非确定有限状态自动机 733

python3.12 在用django5.0创建超级用户时,遇到AttributeError: module ‘hashlib‘ has no attribute ‘pbkdf2_hmac‘的问题

产生问题的原因是python3.12的hashlib没有自带pbkdf2_hmac函数,该函数是加密算法的一种,只要通过别的函数导入pbkdf2_hmac即可。还有一种方法是将django默认使用的pbkdf2_hmac改为hashlib自带的sha2或其他算法返回加密的密码,笔者以后会尝试用此类办法解决问题。2.找到报错文件的位置/usr/local/lib/python3.12/site-packages/django/utils/crypto.py。保存修改的文件,重新执行创建超级用户的命令成功。

weixin_67057943的博客 851

基于STM32L4XX、HAL库的AD7124-8BCPZ模数转换器ADC驱动程序设计

/ 公式: Voltage = (adc_value / (2^23 - 1)) * Vref。// 模式控制位[7:5]=000 (连续转换模式)// 3.2 配置通道0,使其使用AIN0(+)和AIN1(-),并关联到配置0和滤波器0。= 0x14) { // AD7124-8的ID是0x14。// 双极性操作,缓冲AINP/AINN。

zhusl6688的博客 375

Stammering Aliens(后缀数组+二分)

Dr. Ellie Arroway has established contact with an extraterrestrial civilization. However, all efforts to decode their messages have failed so far because, as luck would have it, they have stumbled upo...

自渡的博客 629

YOLOv11改进 | 损失函数改进篇 | EIoU、SIoU、WIoU、DIoU、FocusIoU等二十余种损失函数

这篇文章介绍了YOLOv11的重大改进,特别是在损失函数方面的创新。它不仅包括了多种IoU损失函数的改进和变体,如SIoU、WIoU、GIoU、DIoU、EIOU、CIoU,还融合了“Focus”思想,创造了一系列新的损失函数。这些组合形式的损失函数超过了二十余种,每种都针对特定的目标检测挑战进行优化。文章会详细探讨这些损失函数如何提高YOLOv11在各种检测任务中的性能,包括提升精度、加快收敛速度和增强模型对复杂场景的适应性。

Snu77的博客 6190

UVA 12206 Stammering Aliens(基于哈希值的LCP算法)

UVA 12206 Stammering Aliens(基于哈希值的LCP算法) 题意:给你一个字符串s和m,求出字符串中至少出现m次的最长子串.如果有多解,输出最长字符串的长度以及它出现的最大位置. 分析:其实本题可以用后缀数组来解.下面用哈希值来做.        首先对于一个长为n的字符串,我们定义它的哈希值为(下面的x值是人为设定的一个值): s[0]+s[1]*x+s[2]*x^

code 1641

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

重复出现超过m次的最长的子串的最大下标 后缀数组或Hash+LCP UVA 12206 - Stammering Aliens

题目链接 题意:给定一个字符串,找出重复出现超过m次的字串的最大开始下标 思路:hash大法,需要点人品,然后二分答案,每次利用hash值去找出最大下标即可 代码: #include #include #include using namespace std; const int maxn = 40000 + 10; const int x = 123; int n, m

ACM_10000h的专栏 1010

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

UVA 12206 Stammering Aliens 后缀数组+二分

UVA 12206题意:输入一个m,接下来输入一个仅包含小写字母的字符串,求字符串中至少出现m次的最长子串,输出两个数据,一个是最长子串长度,一个是这些子串中起始位置的最大值。思路:比较水,很明显建立后缀数组,用二分找最长的子串并且用height数组去判断。#include&lt;cstdio&gt; #include&lt;cstring&gt; #include&lt;algorithm&gt...

ccsu_cat 354

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Stammering Aliens (Hash+二分)

Dr. Ellie Arroway has established contact with an extraterrestrial civilization. However, all efforts to decode their messages have failed so far because, as luck would have it, they have stumbled upo...

qq_42434171的博客 553

LA 4513 hash表示字符串后缀

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=&problem=2514&mosmsg=Submission+received+with+ID+1623942 Dr. Ellie Arroway has established cont

ACM,再见! 1416

UVA 12206 - Stammering Aliens(Hash+LCP)

UVA 11107 - Life Forms 题目链接 题意:给定一个字符串,找出重复出现超过m次的字串的最大开始下标 思路:hash大法,需要点人品,然后二分答案,每次利用hash值去找出最大下标即可 代码: #include #include #include using namespace std; typedef unsigned long long

Remilia's 1266

Stammering Aliens

Stammering Aliens Time Limit:2000MS Memory Limit:65536K Description Dr. Ellie Arroway has established contact with an extraterrestrial civilization. However, all ...

weixin_30883311的博客 326

hdu4080---Stammering Aliens(后缀数组+二分)

Problem Description Dr. Ellie Arroway has established contact with an extraterrestrial civilization. However, all efforts to decode their messages have failed so far because, as luck would have it, th

Alex 1166

[HDU 4080] Stammering Aliens (字符串哈希+二分)

链接HDU 4080题意每组数据为一个整数m和一个长度不小于m的字符串,求该字符串的一个子串,该子串在满足出现次数不小于m的同时应尽量长。 输出该长度和最右侧出现的起始位置。如果存在多组数据,输出有最靠近右侧的那组。思路关于子串和长度的题目仿佛都可以用字符串哈希+二分来水一水。 这题仍然是字符串哈希的题目,对这个字符串求哈希,然后二分长度,枚举对应长度的子串哈希。每个哈希值要存储在哈希表里并记录

mysterious 2605

UVALive - 4513 Stammering Aliens [ Hash + 二分 ]

Problem Description Dr. Ellie Arroway has established contact with an extraterrestrial civilization. However, all efforts to decode their messages have failed so far because, as luck would have it, ...

Acer12138的博客 453

HDU 4080 Stammering Aliens(后缀数组)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4080 这个题目知道后缀数组的估计都会做,但是想AC估计要wa个一两下才能AC,其实这个题目也没什么陷阱,就是后缀数组的基本处理方法 二分枚举,但是这个要输出最后出现的位置其实还是比较简单的,但是要注意一个细节,在用height数组比较的时候可能会只计算后面的那个 的位置,忽略的第一个的位置,所以

sunrain的专栏 915

LA 4513 Stammering Aliens(哈希写起来比后缀数组爽多了)

LA  4513

u011276914的专栏 1060

[后缀数组]hdoj 4080:Stammering Aliens

大致题意:     给出一个数字m和一个字符串str,求出str中至少出现m次的最长的子串长度,并且求出这些子串中最靠右的子串的位置。   大致思路:    先求出后缀数组,二分枚举这个长度mid,然后分析height数组的每个大于mid的区间。过程稍复杂,具体看我代码即可。   #include&lt;iostream&gt; #include&lt;cstdio&gt; #...

手上有剑,心中有爱 235
上一篇: uva11107 - Life Forms 后缀数组
下一篇: uva1479 - Graph and Queries Treap名次树
小小小小葱
博客等级 码龄14年 22粉丝 266原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值