CF1056E 哈希

这道题题目看完就知道用哈希枚举以下就好,但是做得时候犯病了,犯了三个错误,大数据上卡了好久

1.不小心把枚举条件放到循环定义里,结果枚举不全

2.做了两次无意义的哈希(把s0s1都哈希出来了,其实从原串里取就行,浪费了时间,T 了几发)

3.这个暂时还不知道为什么错了:因为这道题的枚举在找到一个可能解之后其实像不定方程通解一样,不用+1+1地跳,但是不知道为什么WA18了,等会儿再去找几个数据想想。

下附代码:

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 const int maxn=1000005;
  4 struct Hash
  5 {
  6     int base[4], mod[4];
  7     int tot, hash[4][maxn], pw[4][maxn]; //字符串长度,hash:记从1~i的hash值,pw:记录base^i
  8     Hash()
  9     {
 10         tot = 0;
 11         for (int i = 1; i <= 3; i++)
 12             pw[i][0] = 1;
 13         base[1] = 233;
 14         base[2] = 19260817;
 15         base[3] = 20030714;
 16         mod[1] = 1e9 + 7;
 17         mod[2] = 1e9 + 9;
 18         mod[3] = 998244353;
 19     }
 20 
 21     void init()
 22     {
 23         tot = 0;
 24     }
 25     void insert(int c)
 26     {
 27         tot++;
 28         for (int i = 1; i <= 3; i++)
 29             hash[i][tot] = (1LL * hash[i][tot - 1] * base[i] + c) % mod[i];
 30         for (int i = 1; i <= 3; i++)
 31             pw[i][tot] = (1LL * pw[i][tot - 1] * base[i]) % mod[i];
 32     }
 33     //字符串[l,r]hash值,type为第几个hash
 34     int query(int l, int r, int type)
 35     {
 36         return (hash[type][r] - (1LL * hash[type][l - 1] * pw[type][r - l + 1] % mod[type]) + mod[type]) % mod[type];
 37     }
 38     //判断字符串u的[lu,ru]内的字符串和字符串v的[lv,rv]内的字符串是否相同
 39     friend bool same(Hash &u, int lu, int ru, Hash &v, int lv, int rv)
 40     {
 41         if (ru - lu != rv - lv)
 42             return false;
 43         for (int i = 1; i <= 3; i++)
 44             if (u.query(lu, ru, i) != v.query(lv, rv, i))
 45                 return false;
 46         return true;
 47     }
 48 } h;
 49 char s[100005];
 50 char t[1000005];
 51 int main(){
 52     h.init();
 53     scanf("%s",s+1);
 54     int ls=strlen(s+1),num0=0,num1=0;
 55     for (int i=1; i<=ls; i++){
 56         if (s[i]=='0') num0++;
 57         else num1++;
 58     }
 59     scanf("%s",t+1);
 60     int n=strlen(t+1);
 61     long long res=0;
 62     for (int i=1; i<=n; i++)
 63         h.insert(t[i]);
 64     if (s[1]=='0'){
 65         for (int i=1; n-i*num0>=num1; i++){
 66             if ((n-i*num0)%num1!=0) continue;
 67             int l0=i,l1=(n-i*num0)/num1;
 68             int cnt1=1;
 69             while (s[cnt1]=='0') cnt1++;
 70             if (same(h,1,l0,h,(cnt1-1)*l0+1,(cnt1-1)*l0+l1)) continue;
 71             int st=0,flag=0;
 72             for (int j=1; j<=ls; j++){
 73                 if (s[j]=='0'){
 74                     if (!same(h,st+1,st+l0,h,1,l0)){
 75                         flag=1;
 76                         break;
 77                     }
 78                     st+=l0;
 79                 }
 80                 else {
 81                     if (!same(h,st+1,st+l1,h,(cnt1-1)*l0+1,(cnt1-1)*l0+l1)){
 82                         flag=1;
 83                         break;
 84                     }
 85                     st+=l1;
 86                 }
 87             }
 88             if (!flag) res++;
 89         }
 90         printf("%lld
",res);
 91     }
 92     else {  
 93         for (int i=1; n-i*num1>=num0; i++){
 94             if ((n-i*num1)%num0!=0) continue;
 95             int l1=i,l0=(n-i*num1)/num0;
 96             int cnt0=1;
 97             while (s[cnt0]=='1') cnt0++;
 98             if (same(h,1,l1,h,(cnt0-1)*l1+1,(cnt0-1)*l1+l0)) continue;
 99             int st=0,flag=0;
100             for (int j=1; j<=ls; j++){
101                 if (s[j]=='0'){
102                     if (!same(h,st+1,st+l0,h,(cnt0-1)*l1+1,(cnt0-1)*l1+l0)){
103                         flag=1;
104                         break;
105                     }
106                     st+=l0;
107                 }
108                 else {
109                     if (!same(h,st+1,st+l1,h,1,l1)){
110                         flag=1;
111                         break;
112                     }
113                     st+=l1;
114                 }
115             }
116             if (!flag) res++;
117         }
118         printf("%lld
",res);
119     }
120 }
View Code
原文地址:https://www.cnblogs.com/i-caigou-TT/p/14041501.html