zoukankan      html  css  js  c++  java
  • Clairewd's message /// 字符串hash

    题目大意:

    给定字符串s 是26个字母对应的密文字母

    给定字符串c1 是 密文+部分原文

    原文可能缺损 要求将原文补全输出

    利用s得到密文字母对应的原字母rs

    利用rs翻译c1得到 原文+部分密文c2 

    由于密文肯定是完整的 此时

    c1 完整密文+部分原文

    c2 完整原文+部分密文

    将两个字符串hash 若一段字符相等则对应段的hash值也相等

    枚举原文的长度 就可以得到在c1中原文的开始位置len

    则此时假设 c1中 n-len+1~n 为原文 则c2中1~len为原文

    若此时这两段字符的hash值相等 则假设成立

    #include <bits/stdc++.h>
    using namespace std;
    #define LL long long
    #define ULL unsigned long long
    #define INF 0x3f3f3f3f
    #define mem(i,j) memset(i,j,sizeof(i))
    #define inc(i,l,r) for(int i=l;i<=r;i++)
    #define dec(i,r,l) for(int i=r;i>=l;i--)
    #define gcd(i,j) __gcd(i,j);
    const int maxn=1e5+5;
    const int mod=1e9+7;
    const double eps=1e-8;
    
    typedef unsigned long long ull;
    struct hash_table{
      ull seed=163;
      ull Hash[maxn],temp[maxn];
      void work(char *s,int n){
        temp[0]=1; Hash[0]=0;
        for(int i=1;i<=n;i++)temp[i]=temp[i-1]*seed;
        for(int i=1;i<=n;i++)Hash[i]=(Hash[i-1]*seed+(s[i]-'a'));
      }
      ull get(int l,int r){
        return Hash[r]-Hash[l-1]*temp[r-l+1];
      }
    }h1, h2;
    
    char c1[maxn],c2[maxn];
    char s[30],rs[30];
    
    int main()
    {
        int _; scanf("%d",&_);
        while(_--) {
            scanf("%s%s",s,c1+1);
            inc(i,0,26-1) rs[s[i]-'a']=i+'a';
            int n=strlen(c1+1);
            inc(i,1,n) c2[i]=rs[c1[i]-'a'];
            h1.work(c1,n); h2.work(c2,n);
            // h1对应的 c1是完整密文+部分原文
            // h2对应的 c2是完整原文+部分密文
            int ans=n;
            inc(i,n,n*2-1) { // 枚举整串的长度
                if(i&1) continue; // 奇数长度跳过
                int mid=i/2; // 得到此时密文的长度
                int len=n-mid; // 再得到部分原文的长度
                ULL s1=h1.get(n-len+1,n); // 部分原文的密文
                ULL s2=h2.get(1,len); // 部分原文
                if(s1==s2) { ans=mid; break; }
                // 若两个区间hash值相同 说明两段字符相同
            }
            inc(i,1,ans) printf("%c",c1[i]);
            inc(i,1,ans) printf("%c",c2[i]);
            printf("
    ");
        }
    
        return 0;
    }  
     
    View Code
  • 相关阅读:
    使用mybetis插件的公共方法进行查询
    bootstrap的刷新和查询
    消息队列的使用和注意事项
    MySQL 日期时间计算函数
    mysql基础学习网站
    html装换成字符串的工具、代码辅助工具
    正则校验数字,数字保留两位小数,字母,特殊符号和数字
    HTML表格和表单
    HTML标签
    媒体查询写法
  • 原文地址:https://www.cnblogs.com/zquzjx/p/10547774.html
Copyright © 2011-2022 走看看