zoukankan      html  css  js  c++  java
  • Atcoder ABC E

    Atcoder ABC E - Divisible Substring

    题意

    一个长为n(2e5)的数字串,给一个质数p(1e4),能被p整除的子串(连续)个数

    思路

    因为p是个素数,所以要想到用素数的条件。最朴素的就是dp[i][j]第i位为最低位modp余数是j的子串有多少个,但是转移是np的,我们可以仔细想一想,有什么状态时多余的,转移每次都要乘j10+s[i]-'0'这一个操作有没有意义呢?我们假设p和10互质,其实就是没有意义的,因为p如果和10互质那么对于每个数后面无论添加多少个0都不会改变它和p的整除情况。小证明:添加0就相当于对于一个乘(2*5)的质因数,而p没有2和5的质因数,所以就不会有影响。那么问题就转化成例如s[1]s[2]s[3]s[4]s[5]s[6] 如果s[4]s[5]能够被p整除,那么s[4]s[5]0也能被p整除,也就是说我们只要记录每一个后缀的膜p的余数,相同的两两组合即可。而对于后缀modp等于0的来说,还要额外加上单独取一个的。
    记住,以上是基础p和10互质的情况,事实上大于10的素数肯定不和10互质,可以从唯一分解定理理解。而小于10的有2和5和10互质,只要考虑以2或者以5结尾的子串有几个,本题就解决了

    #include<bits/stdc++.h>
    using namespace std;
    #define pb push_back
    #define F first
    #define S second
    #define mkp make_pair
    #define pii pair<int,int>
    typedef long long ll;
    const int inf=0x3f3f3f3f;
    const int maxn=2e5+5;
    char s[maxn];
    ll dp[10000+5];
    
    int main(){
    	ll n,p;
    	cin>>n>>p;
    	cin>>(s+1);
    	ll ans=0;
    	if(p==2||p==5){
    		for(int i=1;i<=n;i++){
    			if((s[i]-'0')%p==0){
    				ans+=i;
    			}
    		}
    	}
    	else {
    		ll tmp=0;
    		ll base=1;
    		for(int i=n;i>=1;i--){
    			tmp=(tmp+(s[i]-'0')*base)%p;
    			base=(base*10)%p;
    			dp[tmp]++;	
    		}
    		ans+=dp[0]+1ll*dp[0]*(dp[0]-1)/2;
    		for(int i=1;i<=p-1;i++){
    			ans+=1ll*(dp[i]-1)*dp[i]/2;
    		}
    	}
    	cout<<ans;
    	return 0;
    }
    
    
  • 相关阅读:
    python Database Poll for SQL SERVER
    SQLAlchemy表操作和增删改查
    flask动态url规则
    flask配置管理
    一个Flask运行分析
    Function Set in OPEN CASCADE
    Happy New Year 2016
    Apply Newton Method to Find Extrema in OPEN CASCADE
    OPEN CASCADE Multiple Variable Function
    OPEN CASCADE Gauss Least Square
  • 原文地址:https://www.cnblogs.com/ttttttttrx/p/12439866.html
Copyright © 2011-2022 走看看