zoukankan      html  css  js  c++  java
  • Mail.Ru Cup 2018 Round 3 E. Check Transcription (字符串hash)

    Mail.Ru Cup 2018 Round 3 E. Check Transcription

    • 题意:给你一个\(01\)\(s\)和一个字符串\(t\),将\(t\)中的两个不同的子串映射成\(0\)\(1\),问你有多少种不同的映射方法使得\(s\)映射后刚好为\(t\)

    • 题解:先统计\(0\)\(1\)的个数\(cnt0\)\(cnt1\),假设我们映射给\(0\)的长度为\(len_0\)\(1\)\(len_1\),有:\(cnt_0*len_0+cnt_1*len_1=|t|\),可以枚举\(len_0\)的长度,如果合法,就能得到\(len_1\)的长度,同时也自然能得到两个映射的子串,用hash去暴力check是否合法.显然这种方法看上去并没有问题,我们担心的是会不会超时.设\(c=max(cnt_0,cnt_1)\),显然\(c\ge \frac{|s|}{2}\),根据上面的公式,合法的解最多有\(\frac{|t|}{c}\)个,所以最多跑\(|t|+\frac{|t|}{c}*|s|=|t|+2*|t|\)次,前面的这个\(|t|\)应该可以优化掉,但我直接跑了,问题不大,此外这题hash自然溢出会被卡,记得取模

    • 代码

      #include <bits/stdc++.h>
      #define ll long long
      #define ull unsigned long long 
      #define fi first
      #define se second
      #define pb push_back
      #define me memset
      #define rep(a,b,c) for(int a=b;a<=c;++a)
      #define per(a,b,c) for(int a=b;a>=c;--a)
      const int N = 1e7 + 10;
      const int mod = 1e9 + 7;
      const int INF = 0x3f3f3f3f;
      using namespace std;
      typedef pair<int,int> PII;
      typedef pair<ll,ll> PLL;
      ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
      ll lcm(ll a,ll b) {return a/gcd(a,b)*b;}
       
      int n,m;
      int cnt0,cnt1;
      string s,t;
      ll ans=0;
      ull base=19260817;
      ull h[N],p[N];
       
      void init(){
          p[0]=1,h[0]=0;
          for(int i=1;i<=m;++i){
              h[i]=(h[i-1]*base+t[i])%mod;
              p[i]=p[i-1]*base%mod;
          }
      }
       
      ull get_hash(int l,int r){
          return (h[r]-h[l-1]*p[r-l+1]%mod+mod)%mod;
      }
       
      int main() {
          cin>>s>>t;
          n=(int)s.size(),m=(int)t.size();
          s=" "+s,t=" "+t;
          init();
          for(int i=1;i<=n;++i){
              if(s[i]=='0'){
                  cnt0++;
              }
              else{
                  cnt1++;
              }
          }
          for(int i=1;i<=m;++i){
              int len0=i;
              if(m-cnt0*len0<=0) break;
              if((m-cnt0*len0)%cnt1==0){
                  int len1=(m-cnt0*len0)/cnt1;
                  ull res0=0,res1=0;
                  string now0,now1;
                  int now=1;
                  for(int j=1;j<=n;++j){
                      if(s[j]=='0'){
                          if(!res0) res0=get_hash(now,now+len0-1);
                          now+=len0;
                      }
                      else{
                          if(!res1) res1=get_hash(now,now+len1-1);
                          now+=len1;
                      }
                  }
                  if(res0==res1) continue;
                  bool flag=true;
                  int pos=1;
                  for(int j=1;j<=n;++j){
                      if(s[j]=='0'){
                         ull cur=get_hash(pos,pos+len0-1);
                         if(cur!=res0){
                             flag=false;
                             break;
                         }
                         pos=pos+len0;
                      }
                      else{
                          ull cur=get_hash(pos,pos+len1-1);
                          if(cur!=res1){
                              flag=false;
                              break;
                          }
                          pos=pos+len1;
                      }
                  }
                  if(flag) ans++;
              }
          }	
          cout<<ans<<endl;
          return 0;
      }
      
  • 相关阅读:
    HDU 2444 The Accomodation of Students (判断是否是二分图,然后求最大匹配)
    HDU 1045 Fire Net (二分匹配)
    Leangoo如何颠覆传统项目管理软件?
    团队协作神器:Leangoo
    Leangoo-让工作更简单
    leangoo 轻量级项目协作和列表管理平台
    团队协作中的“贵族”leangoo
    使用leangoo实现多泳道任务看板
    项目管理工具到底应该为谁服务?
    《精益创业实战》读书笔记
  • 原文地址:https://www.cnblogs.com/lr599909928/p/15572592.html
Copyright © 2011-2022 走看看