• 暑假集训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 }
  • 相关阅读:
    Permutation Sequence
    Sqrt(x)
    Search in Rotated Sorted Array ||
    [STL]list的erase正确与错误用法
    一个支持Git应用编程开发的第三方库(API)
    VC++生成full dump文件
    Maven构建C++工程的插件-NAR
    VC++ Watch窗口查看指针指向的数组
    Android SDK更新失败的解决方法
    ADT20新建项目Android Support library not installed问题
  • 原文地址:https://www.cnblogs.com/keximeiruguo/p/16456708.html
Copyright © 2020-2023  润新知