O(nl)做法TLE救命
查看原帖
O(nl)做法TLE救命
726870
Rainber楼主2024/9/22 20:26

代码:

#include<stdio.h>
#include<malloc.h>
#define Prime1 131
#define Prime2 13331
unsigned int hash1(char *s)
{
	unsigned int h=0;
	while(*s!='\0')
	{
		h*=Prime1;
		h+=*s;
		s++;
	}
	return h;
}
unsigned int hash2(char *s)
{
	unsigned int h=0;
	while(*s!='\0')
	{
		h*=Prime2;
		h+=*s;
		s++;
	}
	return h;
}
struct node//size:16
{
	unsigned int h1,h2;
	int cnt; 
	void *next;
} htable[1000007];
void hmark(unsigned int h1,unsigned int h2)
{
	struct node *p=&htable[h1%1000007];
	while(p->next!=NULL)
	{
		p=p->next;
		if(p->h1==h1&&p->h2==h2)
		{
			p->cnt++;
			return;
		}
	}
	p->next=(struct node *)malloc(16);
	p=p->next;
	p->next=NULL;
	p->h1=h1;
	p->h2=h2;
	p->cnt=1;
}
int hexist(unsigned int h1,unsigned int h2)
{
	struct node *p=&htable[h1%1000007];
	while(p->next!=NULL)
	{
		p=p->next;
		if(p->h1==h1&&p->h2==h2)
		{
			return p->cnt;
		}
	}
	return 0;
}
unsigned int hprocess(unsigned int hori,unsigned int *ppow,int bit,char ori,char to,int l)
{
	return hori+(to-ori)*ppow[l-bit-1];
}
unsigned int p1pow[201];
unsigned int p2pow[201];
char s[201];
int main()
{
	int i,n,l,j,h1,h2,sh1,sh2,ans=0;
	char r;
	scanf("%d%d%*d",&n,&l);
	p1pow[0]=1;
	p2pow[0]=1;
	for(i=1;i<l;++i)
	{
		p1pow[i]=p1pow[i-1]*Prime1;
		p2pow[i]=p2pow[i-1]*Prime2;
	}
	for(i=0;i<n;++i)
	{
		scanf("%s",s);
		sh1=hash1(s);
		sh2=hash2(s);
		for(j=0;j<l;++j)
		{
			h1=hprocess(sh1,p1pow,j,s[j],0x7F,l);
			h2=hprocess(sh2,p2pow,j,s[j],0x7F,l);
			ans+=hexist(h1,h2);
			hmark(h1,h2);
		}
	}
	printf("%d",ans);
	return 0;
}

寄路 TLE 60pts

计算:可能的哈希值只有40000个(双哈希算作一个)但是哈希表是1000007的绰绰有余,而且我的代码肉眼可见的 O(NL)O(NL),正解是 O(NL×logN)O(NL \times logN)

2024/9/22 20:26
加载中...