已过,但不理解
查看原帖
已过,但不理解
1268524
DX3906_ourstar楼主2025/1/19 11:56

rt,若干年前用 STL 切掉了本题,一直以为本题很水,直到今天正式学哈希才发现有点玄学。

现在有两份代码。一份没有将输入以字符串的形式存储起来,而是使用 getchar() 一个字符一个字符地读入并计算哈希值;另一份就是传统的思路,老老实实读入字符串,传参给 hashh 函数来计算哈希值。除此以外,两种做法别无二致。

某种意义上来讲,前者更优,因为它只用了一个字符,空间、时间开销更小;但事实上,它无法通过,而且下载测试点后本地运行,发现答案并未出错。后者能够通过,但慢得多。

贴上两份代码。这是前一种做法的:

#include<iostream>
#include<string>
#include<algorithm>
#define ull unsigned long long
#define p 212370440130137957ll
using namespace std;

namespace OIfast{
	
	inline int read(){
		int n=0,f=1;
		char c=getchar();
		while(c<'0'||c>'9'){
			if(c=='-')f=-1;
			c=getchar();
		}
		while(c>='0'&&c<='9')n=(n*10+c-'0')%p,c=getchar();
		return n*f;
	}
	
	inline void print(int n){
		if(n<0)putchar('-'),n=-n;
		if(n>=10)print(n/10);
		putchar(n%10+'0');
		return ;
	}
	
	inline void write(int n,char c){
		print(n),putchar(c);
		return ;
	}
	
}using namespace OIfast;

const int N=1e7+5;

int n,ans=1;
ull a[N];

signed main(){
	n=read();
	for(int i=1;i<=n;++i){
		ull hash=0;
		char c=getchar();
		while(c!=' '&&c!='\n'){
			hash=(hash*191+(ull)c)%p;
			c=getchar();
		}
		a[i]=hash;
	}
	sort(a+1,a+n+1);
	for(int i=2;i<=n;++i)if(a[i]!=a[i-1])++ans;
	write(ans,'\n');
	return 0;
}

这是后一种做法的:

#include<iostream>
#include<string>
#include<algorithm>
#define ull unsigned long long
#define p 212370440130137957ll
using namespace std;

namespace OIfast{
	
	inline int read(){
		int n=0,f=1;
		char c=getchar();
		while(c<'0'||c>'9'){
			if(c=='-')f=-1;
			c=getchar();
		}
		while(c>='0'&&c<='9')n=(n*10+c-'0')%p,c=getchar();
		return n*f;
	}
	
	inline void print(int n){
		if(n<0)putchar('-'),n=-n;
		if(n>=10)print(n/10);
		putchar(n%10+'0');
		return ;
	}
	
	inline void write(int n,char c){
		print(n),putchar(c);
		return ;
	}
	
}using namespace OIfast;

const int N=1e7+5;

int n,ans=1;
ull a[N];

inline ull hashh(string s){
	int l=s.size();
	ull x=0;
	for(int i=0;i<l;++i){
		x=(x*191+(ull)s[i])%p;
	}
	return x;
}

signed main(){
	n=read();
	for(int i=1;i<=n;++i){
		string s;
		cin>>s;
		a[i]=hashh(s);
	}
	sort(a+1,a+n+1);
	for(int i=2;i<=n;++i)if(a[i]!=a[i-1])++ans;
	write(ans,'\n');
	return 0;
}

就这 B 板子折腾我一早上了,旁边同学都切了几道蓝了而我还在研究这道橙,非常红温。

2025/1/19 11:56
加载中...