/ Randle /

记录详情

Accepted


  
# 状态 耗时 内存占用
#1 Accepted 1ms 204.0 KiB
#2 Accepted 1ms 204.0 KiB
#3 Accepted 1ms 208.0 KiB
#4 Accepted 1ms 204.0 KiB
#5 Accepted 8ms 472.0 KiB
#6 Accepted 7ms 488.0 KiB
#7 Accepted 34ms 1.871 MiB
#8 Accepted 121ms 1.875 MiB
#9 Accepted 117ms 1.871 MiB
#10 Accepted 93ms 1.77 MiB

代码

#include<bits/stdc++.h>
#define fre(x) freopen(#x".in","r",stdin);freopen(#x".out","w",stdout)
using namespace std;
const long long p=31,mod=1e9+7;
long long len,m,b[50050],a[50050],Pow[50050],Hash[50050],ans;
char s[50050];
bool Max(long long x,long long y)
{
	if(x==y) return 1;
	long long l=0,r=m,tot=-1;
	while(l<=r)
	{
		long long mid=(l+r)>>1;
		long long hash1=((Hash[x+mid-1]-Hash[x-1]*Pow[mid]%mod)%mod+mod)%mod;
		long long hash2=((Hash[y+mid-1]-Hash[y-1]*Pow[mid]%mod)%mod+mod)%mod;
		if(hash1==hash2)
		{
			l=mid+1;
			tot=mid;
		}
		else r=mid-1;
	}
	if(tot>=m) return 1;
	return s[x+tot]<s[y+tot];
}
void merge(long long l,long long r)
{
	if(l==r) return;
	long long mid=(l+r)>>1;
	merge(l,mid);
	merge(mid+1,r);
	long long i=l,j=mid+1,k=l;
	while(i<=mid&&j<=r)
	{
		long long ok=Max(a[i],a[j]);
		if(ok) b[k++]=a[i++];
		else b[k++]=a[j++],ans+=mid-i+1;
	}
	while(i<=mid) b[k++]=a[i++];
	while(j<=r) b[k++]=a[j++];
	for(long long i=l;i<=r;i++) a[i]=b[i];
}
int main()
{
	scanf("%lld%lld\n",&len,&m);
	scanf("%s",s+1);
	Hash[0]=0;
	Pow[0]=1;
	for(long long i=1;i<=len;i++)
	{
		Hash[i]=((Hash[i-1]*p)%mod+s[i]-'a'+1)%mod;
		Pow[i]=(Pow[i-1]*p)%mod;
//		printf("%lld %lld\n",Hash[i],Pow[i]);
		a[i]=i;
	}
	merge(1,len);
	printf("%lld",ans);
	return 0;
}

信息

递交者
类型
递交
题目
后缀数组
题目数据
下载
语言
C++
递交时间
2019-12-13 16:15:53
评测时间
2019-12-13 16:15:53
评测机
分数
100
总耗时
388ms
峰值内存
1.875 MiB