码迷,mamicode.com
首页 > 其他好文 > 详细

D-【乐】k进制数(同余)

时间:2019-05-31 23:30:39      阅读:138      评论:0      收藏:0      [点我收藏+]

标签:amp   进制   typedef   print   lse   c++   一起   line   bit   

题目

https://ac.nowcoder.com/acm/contest/907/D

做法

\((x)_k\)定义编号,如果\(a+b\)加到一起能进一位,\(a+b\rightarrow 1+(a+b-k)=a+b-(k-1)\),故\(d(a_{l,r})=\sum\limits_{i=l}^r a_i\% k-1\)

但我们发现\(k-1\)这一块缺失了,显然为\(0\)当且仅当区间均为\(0\),其他情况得出\(0\)的时候实际结果为\(k-1\)

  • \(b=0\):全\(0\)区间个数

  • \(b=k-1\):满足\(/%(k-1)=0\)的个数-全\(0\)区间个数

  • 其他情况:\(a_{l,r}=sum_r-sum_{l-1}\%(k-1),sum_r-sum_{l-1}\equiv b (\%k-1),sum_r-b\equiv sum_{l-1}(\%k-1)\)

    Code

#include<bits/stdc++.h>
typedef long long LL;
const LL maxn=1e6+9;
inline LL Read(){
    LL x(0),f(1); char c=getchar();
    while(c<'0' || c>'9'){
        if(c=='-') f=-1; c=getchar();
    }
    while(c>='0' && c<='9'){
        x=(x<<3)+(x<<1)+c-'0'; c=getchar();
    }return x*f;
}
LL k,b,n,ret,num,ze;
LL a[maxn],sum[maxn];
std::map<LL,LL> cnt;
int main(){
    k=Read(); b=Read(); n=Read();
    for(LL i=1;i<=n;++i) a[i]=Read();
    for(LL i=1;i<=n;++i){
        sum[i]=(sum[i-1]+a[i])%(k-1);
        if(!a[i]){
            ++num;
            ze+=num;
        }else
            num=0;
    }
    if(!b){
        printf("%lld\n",ze);
        return 0;
    }
    cnt[0]++;
    for(LL i=1;i<=n;++i){
        LL val((sum[i]-b+k-1)%(k-1));
        ret+=cnt[val];
        ++cnt[sum[i]];
    }
    if(b==k-1) ret-=ze;
    printf("%lld\n",ret);
    return 0;
}

D-【乐】k进制数(同余)

标签:amp   进制   typedef   print   lse   c++   一起   line   bit   

原文地址:https://www.cnblogs.com/y2823774827y/p/10957899.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!