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