zoukankan      html  css  js  c++  java
  • 前缀和

    #include<bits/stdc++.h>
    using namespace std;
    long long sum[100000+10]={0},ans,n,a[100000+10],k,c[100000+10]={0};
    //前缀和,所谓的前缀和就是sumi-sumj获得区间的值
    //看到倍数想到数论,尤其是没有别的数论题
    //因为sum[i]-sum[j]=sum i+1 -- j,那么(sum[i]-sum[j])%k=0,即为所求,那么sum[i],sum[j],mod k 的值一样
    //两个sum的得到一个区间,假设sum mod k一样的有2个,那么是1个区间,有3个是1+2个区间,即每次把新来的sum和已经有的匹配可以得到i-1个
    //这里还有一个问题,sum i - sum j,得到的是i+1到j,那么从1开始求sum无法表示1-。。。的区间,所以要算上sum0,即c[0]=1;
    //还有一种理解:求出mod k同样的个数,存到c中,那么就得到了几个边界,他们是有序的,对其求区间个数=(n-1)*n/2
    int main() {
    cin>>n>>k;
    for(int i=1;i<=n;i++) cin>>a[i];
    c[0]=1;
    for(int i=1;i<=n;i++){
    sum[i]=(sum[i-1]+a[i])%k;
    c[sum[i]]++;//余数计数
    ans+=c[sum[i]]-1;//求出同余数对应的区间数
    }
    cout<<ans;
    return 0;
    }

  • 相关阅读:
    C#学习五
    C#学习二
    C#学习五
    完成车牌识别,自行拍车牌图片进行上传并查看结果
    C#学习
    简述ASP.NET网站开发步骤
    C#学习四
    C#学习三
    完成身份证识别,自行拍摄身份证图片进行上传并查看结果
    C#学习总结
  • 原文地址:https://www.cnblogs.com/MorrowWind/p/12416305.html
Copyright © 2011-2022 走看看