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
  • 相关阅读:
    再谈用java实现Smtp发送邮件之Socket编程
    Android TextView设置个别字体样式
    Spring4.0MVC学习资料,注解自己主动扫描bean,自己主动注入bean(二)
    Angular团队公布路线图,并演示怎样与React Native集成
    [LeetCode]Remove Element
    poj2481 Cows
    Spark SQL 源代码分析之Physical Plan 到 RDD的详细实现
    MySQL5.6 怎样优化慢查询的SQL语句 -- 慢日志介绍
    容器使用笔记(List篇)
    【Java编程】建立一个简单的JDBC连接-Drivers, Connection, Statement and PreparedStatement
  • 原文地址:https://www.cnblogs.com/zquzjx/p/10547774.html
Copyright © 2011-2022 走看看