Java教程

暑假集训Day4 A (哈希)

本文主要是介绍暑假集训Day4 A (哈希),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

题目链接在本地,简化以后的题意就是在一个长度为2*n的序列中有一个长度为n的滑动窗口,问能框出来多少不同的序列。

比较典型的哈希题,跟着rainy学习了哈希的经典操作,就是设两个哈希模数,算出两个哈希值,这样两个哈希都冲突的概率是非常非常低的!

这题还需要学的就是对于滑动窗口来说哈希的写法,溢出的最高位直接按模数减掉对应位乘上次幂就行了,减到小数就加一个MOD就行。

以上两个是哈希的经典操作。

tips:查询map中是否有某个值,可以用.count()函数

 

 1 #include "bits/stdc++.h"
 2 #define mp(a,b) make_pair(a,b)
 3 using namespace std;
 4 typedef long long LL;
 5 const int MAX=1e5+5;
 6 const int MOD1=1e9+7;
 7 const int MOD2=1e9+9;
 8 LL n,a[MAX<<1],bas1,bas2,bas1n,bas2n,ck1,ck2,ans;
 9 map <pair<LL,LL>,int> p;
10 int main(){
11 //    freopen ("a.in","r",stdin);
12 //    freopen ("a.out","w",stdout);
13     LL i,j;
14     bas1=999983,bas2=999979;
15     while (scanf("%lld",&n)!=EOF){
16         p.clear();
17         ans=0;
18         for (i=1;i<=n;i++) scanf("%lld",&a[i]);
19         for (i=n+1;i<=2*n;i++) a[i]=a[i-n];
20         bas1n=bas2n=1;
21         for (i=1;i<n;i++){
22             bas1n=bas1n*bas1%MOD1;
23             bas2n=bas2n*bas2%MOD2;
24         }
25         ck1=ck2=0;
26         for (i=1;i<=n;i++){
27             ck1=(ck1*bas1%MOD1+a[i])%MOD1;
28             ck2=(ck2*bas2%MOD2+a[i])%MOD2;
29         }
30         p[mp(ck1,ck2)]=1;
31         ans++;
32         for (i=n+1;i<2*n;i++){
33             ck1=(((ck1-a[i-n]*bas1n%MOD1)+MOD1)*bas1%MOD1+a[i])%MOD1;
34             ck2=(((ck2-a[i-n]*bas2n%MOD2)+MOD2)*bas2%MOD2+a[i])%MOD2;
35             if (p.count(mp(ck1,ck2))==0){
36                 p[mp(ck1,ck2)]=1;
37                 ans++;
38             }
39 //            cout<<ck1<<' ';
40         }
41         reverse(a+1,a+2*n+1);
42         ck1=ck2=0;
43         for (i=1;i<=n;i++){
44             ck1=(ck1*bas1%MOD1+a[i])%MOD1;
45             ck2=(ck2*bas2%MOD2+a[i])%MOD2;
46         }
47         if (p.count(mp(ck1,ck2))==0){
48             p[mp(ck1,ck2)]=1;
49             ans++;
50         }
51         for (i=n+1;i<2*n;i++){
52             ck1=(((ck1-a[i-n]*bas1n%MOD1)+MOD1)*bas1%MOD1+a[i])%MOD1;
53             ck2=(((ck2-a[i-n]*bas2n%MOD2)+MOD2)*bas2%MOD2+a[i])%MOD2;
54             if (p.count(mp(ck1,ck2))==0){
55                 p[mp(ck1,ck2)]=1;
56                 ans++;
57             }
58         }
59         printf("%d\n",ans);
60     }
61     return 0;
62 }

 

这篇关于暑假集训Day4 A (哈希)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!