求助这段代码的复杂度
查看原帖
求助这段代码的复杂度
736062
bengshakala1楼主2023/10/30 13:21

统计部分n次,通过 略加优化地跳跃 寻找上一个合法且相同的字符,个人感觉 最坏复杂度是n^2,优化也只是常数层面的 ,但是在官方数据下AC,故来求助谷民:请问这段代码的复杂度如何,为什么如此优化后(在gtnxt中借助nx寻找下一个字)可以AC而暴力跳(在gtnxt中线性寻找下一个字)不可以

#include<iostream>
#include<fstream>
using namespace std;

long ans=0;
long nx[2000005]; //以类似链式前向星的方法存储下一个相同的字
long mn[2000005]; //以data[i]为字符串结尾,最多匹配mn[i]个字串
long ml[2000005]; //以data[i]为字符串结尾,最长可以匹配长度为ml[i]的字串

void init(long n,char* data)
{
    int tmp[26];

	for(long i=0;i<26;i++)
    {
        tmp[i]=-1;
    }
    for(int i=0;i<n;i++)
    {
        nx[i]=tmp[data[i]-'a'];
        tmp[data[i]-'a']=i;
    }
}

void cnt(long n)
{
	for(long i=0;i<n;i++)
		ans+=mn[i];
	return;
}

long getnxt(char* data,long l,long r,const char e)//e是旧版本(线性查找)的残留,现在没有意义
{
    for(long i=nx[r+1];i>=l;i=nx[nx[i]])
    {
        if(r-i==ml[r]-ml[i])
            return i;
    }
    return -1;
}

void solve(long n,char* data)
{
    
    if(data[0]==data[1])
        mn[1]=1,ml[1]=2;
    for(long i=2;i<n;i++)
    {
        if(data[i]==data[i-1])
        {
            if(i==1)
            {
                mn[i]=1;
                ml[i]=2;
            }
            else
            {
                mn[i]=mn[i-2]+1;
                ml[i]=ml[i-2]+2;
            }
        }
        else
        {
            long nxt=getnxt(data,(i-ml[i-1]-1)>=0?(i-ml[i-1]-1):0,i-1,data[i]);
            if(nxt==-1)
                ;
            else if(nxt==0)
            {
                mn[i]=1;
                ml[i]=i+1;
            }
            else
            {
                mn[i]=mn[nxt-1]+1;
                ml[i]=i-nxt+1+ml[nxt-1];
            }
        }
    }
}

int main()
{
	long n;
	char data[2000005];
	cin>>n;
	cin>>data;

	init(n,data);
	solve(n,data);
	cnt(n);

	cout<<ans<<endl;
	return 0;
}
2023/10/30 13:21
加载中...