zoukankan      html  css  js  c++  java
  • BJTU 1867. try a try, ac is OK

    题意:求一个数字串在模p意义下,子串表示的数等于m的个数(p为质数)

    暴力想法:O(n2)枚举子串,O(n2)预处理每个串代表的数字,O(1)判断

    预处理空间不够,改为O(n)预处理每个后缀f[i],需要的串[i,j)即为(dfrac{f[i]-f[j]}{10^{n-j+1}})

    也就是我们需要

    (dfrac{f_i-f_j}{10^{n-j+1}}equiv mmod p)

    同乘(10^{n-j+1})后移项,左侧是仅含有i的式子,右侧是仅含有j的式子

    (f_iequiv 10^{n-j+1}m+f_jmod p)

    开桶存f[i]%p出现次数,O(1)统计,复杂度O(n),非常美好

    然后这样就Wrong Answer

    举个例子:

    (1 otequiv2mod 5)

    同乘10

    (10equiv20mod5)

    问题在哪?如果反过来看俩式子,显然就错了,从来没人说过“同除”这样的性质啊

    也就是同乘性确实成立,但我一直理解成充要条件了,明知没有“同除性”这样的东西,也就说明了它只是充分的(对于一个对的式子)

    怎么才能充要呢?当乘的数(perp)p即可

    所幸p是质数,需要乘的数只是10的k次幂,只含有2或5,所以特判一下2或5即可(这俩数正好也很好特判)

    哎..

    #include<bits/stdc++.h>
    
    using namespace std;
    
    inline int rd(){
    	int ret=0,f=1;char c;
    	while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
    	while(isdigit(c))ret=ret*10+c-'0',c=getchar();
    	return ret*f;
    }
    #define pc putchar
    #define space() pc(' ')
    #define nextline() pc('
    ')
    void pot(int x){if(!x)return;pot(x/10);pc('0'+x%10);}
    void out(int x){if(!x)pc('0');if(x<0)pc('-'),x=-x;pot(x);}
    
    typedef long long ll;
    
    const int MAXN = 500005;
    
    char S[MAXN];
    int f[MAXN],b[MAXN],s[MAXN];
    int n,p,m;
    
    int sh[MAXN];
    
    int mul(int x,int y){
        ll xx=x,yy=y;
        ll ret=(xx*yy)%p;
        return (int)ret;   
    }
    
    void spsolve(){
        ll ans=0;
        for(int i=1;i<=n;i++){
            if(s[i]%p==m) ans+=i;
        }
        cout<<ans;
    }
    
    int main(){
        scanf("%s",S+1);
        p=rd();m=rd();
        n=strlen(S+1);
        for(int i=1;i<=n;i++) s[i]=S[i]-'0'; 
        if(p==5||p==2) return spsolve(),0;
        sh[0]=1;
        for(int i=1;i<=n+1;i++) sh[i]=(sh[i-1]*10)%p;
        ll ans=0;
        for(int i=n;i>=1;i--)
            f[i]=(f[i+1]+(sh[n-i]*s[i])%p)%p;
        for(int i=1;i<=n+1;i++){
            ans+=1ll*b[(f[i]+mul(m,sh[n-i+1]))%p];
            b[f[i]%p]++;
        }
        cout<<ans<<endl;
    	return 0;
    }
    
  • 相关阅读:
    我的第二个思维导图,用来介绍框架
    如何减少基于DataSet框架的代码输入量(一)
    近日
    关于客户端如何获取服务器时间的方法
    匹配用逗号分隔的数字(防sql注入检查)
    十六进制字符串转整形
    sql获取自增行号
    body不出现滚动条方法
    vs2010 无法调试 无法进入断点 断点无效
    Textarea 高度自适应 根据内容自适应高度
  • 原文地址:https://www.cnblogs.com/ghostcai/p/13669601.html
Copyright © 2011-2022 走看看