cf待补 (hash 的写法)

别人的代码:

#include <bits/stdc++.h>

#define mp make_pair
#define pb push_back
#define f first
#define s second
#define ll long long

using namespace std;

const int N = int(1e6) + 10;
const int mod1 = int(1e9) + 21, mod2 = int(1e9) + 5133, base1 = 10, base2 = 10;

ll h1[N],h2[N],p1[N],p2[N];
int n;
char s[N];

ll hash1(int l,int r){
    ll res = (h1[r] - h1[l-1] * p1[r-l+1]) % mod1;
    if(res < 0) res += mod1;
    return res;
}

ll hash2(int l,int r){
    ll res = (h2[r] - h2[l-1] * p2[r-l+1]) % mod2;
    if(res < 0) res += mod2;
    return res;
}

bool check(int j,int a,int b){
    if(a <= 0 || b <= 0) return 0;
    if(max(a,b) > (n - j + 1)) return 0;
    if(s[1] == '0' && a > 1) return 0;
    if(s[a + 1] == '0' && b > 1) return 0;
    if(s[a + b + 1] == '0' && (n - j + 1) > 1) return 0;
    if((hash1(1,a) + hash1(a + 1,a + b)) % mod1 != hash1(a + b + 1, n)) return 0;
    if((hash2(1,a) + hash2(a + 1,a + b)) % mod2 != hash2(a + b + 1, n)) return 0;
    for(int i = 1; i <= a; i++){
        putchar(s[i]);
    }
    putchar('+');
    for(int i = a + 1; i <= a + b; i++){
        putchar(s[i]);
    }
    putchar('=');
    for(int i = a + b + 1; i <= n; i++){
        putchar(s[i]);
    }
    exit(0);
}

int main () {
    scanf("%s",s + 1);
    n = strlen(s + 1);
    p1[0] = p2[0] = 1;
    for(int i = 1; i <= n; i++){
        h1[i] = (h1[i - 1] * base1 + s[i] - '0') % mod1;
        h2[i] = (h2[i - 1] * base2 + s[i] - '0') % mod2;
        p1[i] = p1[i - 1] * base1 % mod1;
        p2[i] = p2[i - 1] * base2 % mod2;
        if(h1[i] < 0) h1[i] += mod1;
        if(h2[i] < 0) h2[i] += mod2;
    }
    int len = 0;
    for(int j = 3; j <= n; j++){
        len = (n - j + 1);
        check(j, len, n - len - len);
        check(j, len - 1, n - len - len + 1);
        check(j, n - len - len, len);
        check(j, n - len - len + 1, len - 1);
    }
return 0;
}
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define maxn 1001000
ll qpow(ll a,ll m,ll mod)
{
    ll ret=1;
    while(m>0)
    {
        if(m&1) ret=ret*a%mod;
        a=a*a%mod;
        m>>=1;
    }
    return ret;
}
ll p[]={1000000093,1000000097,1000000103,1000000123,1000000181};
ll pre[maxn][5];
ll tmp[5];
char s[maxn];
int num[maxn],n;
ll inv[maxn][5];
void init()
{
    for(int i=0;i<5;++i) tmp[i]=1;
    for(int i=n-1;i>=0;--i)
        for(int j=0;j<5;++j)
        {
            pre[i][j]=num[i]*tmp[j]%p[j];
            tmp[j]=tmp[j]*10%p[j];
        }
    for(int i=1;i<n;++i)
        for(int j=0;j<5;++j)
        {
            pre[i][j]+=pre[i-1][j];
            if(pre[i][j]>=p[j]) pre[i][j]-=p[j];
        }
    memset(inv,-1,sizeof(inv));
}
int fi,se,thr;
ll get_inv(int tim,int id)
{
    if(inv[tim][id]!=-1) return inv[tim][id];
    ll al=tim*(p[id]-2)%(p[id]-1);
    return inv[tim][id]=qpow(10,al,p[id]);
}
ll get_has(int l,int r,int id)
{
    ll ret=pre[r][id]-(l>0?pre[l-1][id]:0);
    if(ret<0) ret+=p[id];
    ret=ret*get_inv(n-1-r,id)%p[id];
    return ret;
}
void judge()
{
    if(fi<=0||se<=0||thr<=0) return;
    if(max(fi,se)>thr) return;
    if(fi>1&&num[0]==0) return;
    if(se>1&&num[fi]==0) return;
    if(thr>1&&num[fi+se]==0) return;
    for(int i=0;i<5;++i)
        if((get_has(0,fi-1,i)+get_has(fi,fi+se-1,i))%p[i]!=get_has(fi+se,n-1,i))
            return;
    //
    for(int i=0;i<fi;++i) printf("%d",num[i]);
    putchar('+');
    for(int i=fi;i<fi+se;++i) printf("%d",num[i]);
    putchar('=');
    for(int i=fi+se;i<n;++i) printf("%d",num[i]);
    puts("");
    exit(0);
}
int main()
{
    scanf("%s",s); n=strlen(s);
    for(int i=0;i<n;++i) num[i]=s[i]-'0';
    init();
    for(int i=0;i<n;++i)
    {
        fi=i+1;
        se=(n-fi)/2;
        thr=n-fi-se;
        judge();
        thr=fi;
        se=n-fi-thr;
        judge();
        thr=fi+1;
        se=n-fi-thr;
        judge();
    }
    return 0;
}
#include <bits/stdc++.h>
using namespace std;

#define LL long long
#define N 1000020
#define K 10
#define M 1000020

int p[N], cnt, np[N];
vector<int> rp;
int pw[K][M], h[K][M];
char s[M];
int len;
int A[K], B[K], C[K];

void init() {
    for(int i = 2; i < N; ++i) {
        if(!np[i]) p[cnt++] = i;
        for(int j = 0; j < cnt && i * p[j] < N; ++j) {
            np[i * p[j]] = 1;
            if(i % p[j] == 0) break;
        }
    }
    for(int i = 0, j = cnt - 1; i < K; ++i, --j) {
        rp.push_back(p[j]);
    }
    for(int i = 0; i < K; ++i) {
        pw[i][0] = 1;
        for(int j = 1; j < M; ++j) {
            pw[i][j] = pw[i][j - 1] * 10 % rp[i];
        }
    }
}
int calc(int id, int l, int r) {
    int ret = (h[id][r] - 1LL * h[id][l - 1] * pw[id][r - l + 1] % rp[id]);
    if(ret < 0) ret += rp[id];
    return ret;
}
void get_mod(int l, int r, int *x) {
    for(int i = 0; i < K; ++i) {
        x[i] = calc(i, l, r);
    }
}
void check(int &x, int &y, int a, int b, int c) {
    if(a < 0 || b < 0) return;
    if(s[1] == '0' && a != 1) return;
    if(s[a + 1] == '0' && b != 1) return;
    if(s[a + b + 1] == '0' && c != 1) return;
    get_mod(1, a, A);
    get_mod(a + 1, a + b, B);
    get_mod(a + b + 1, a + b + c, C);
    bool flag = 1;
    for(int i = 0; i < K; ++i) {
        if((A[i] + B[i]) % rp[i] != C[i]) {
            flag = 0;
            break;
        }
    }
    if(flag) x = a, y = b;
}
int main() {
    init();
    scanf("%s", s + 1);
    len = strlen(s + 1);
    for(int i = 0; i < K; ++i) {
        for(int j = 1; j <= len; ++j) {
            h[i][j] = (h[i][j - 1] * 10 + s[j] - 48) % rp[i];
        }
    }
    int x = -1, y = -1;
    for(int i = 1; i <= len; ++i) {
        if(3 * i < len || 2 * i > len) continue;
        check(x, y, len - 2 * i, i, i);
        check(x, y, len - 2 * i + 1, i - 1, i);
        check(x, y, i, len - 2 * i, i);
        check(x, y, i - 1, len - 2 * i + 1, i);
        if(x != -1) break;
    }
    for(int i = 1; i <= x; ++i) putchar(s[i]);
    putchar('+');
    for(int i = x + 1; i <= x + y; ++i) putchar(s[i]);
    putchar('=');
    for(int i = x + y + 1; i <= len; ++i) putchar(s[i]);
    puts("");
    return 0;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值