k倍区间

用前缀和来求区间和,然后用一个二重循环穷举,但是因为问题规模为100000,所以超时(28分)

超时代码:

#include <stdio.h>
#include <memory.h>
#include <math.h>
#include <string>
#include <string.h>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <map>


#define I scanf
#define OL puts
#define O printf
#define F(a,b,c) for(a=b;a<c;a++)
#define FF(a,b) for(a=0;a<b;a++)
#define FG(a,b) for(a=b-1;a>=0;a--)
#define LEN 100010
#define MAX 0x06FFFFFF
#define V vector<int>
#define ll long long

using namespace std;

ll sum[LEN]; 

int main(){
//    freopen("D:/CbWorkspace/blue_bridge/k倍区间.txt","r",stdin);
    int i,j,n,k,ans=0;
    I("%d%d",&n,&k);
    FF(i,n){
        I("%d",&j);
        sum[i+1]=sum[i]+j;
    }
    for(i=1;i<=n;i++){
        for(j=i;j<=n;j++){
            int t=(sum[j]-sum[i-1]);
            if((sum[j]-sum[i-1])%k==0)
                ans++;
        }
    }
    printf("%d
",ans);
    return 0;
}
View Code

观看了大佬的AC代码,终于明白怎么回事了。一句话, 计算前缀和然后取余k, 如果前i项和取余k与前j项和取余k后相同,那么i到j这个区间和为k的倍数

注意ans,cnt,sum都要开 long long

AC代码:

#include <stdio.h>
#include <memory.h>
#include <math.h>
#include <string>
#include <string.h>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <map>


#define I scanf
#define OL puts
#define O printf
#define F(a,b,c) for(a=b;a<c;a++)
#define FF(a,b) for(a=0;a<b;a++)
#define FG(a,b) for(a=b-1;a>=0;a--)
#define LEN 100010
#define MAX 0x06FFFFFF
#define V vector<int>
#define ll long long

using namespace std;

ll sum[LEN]; 
ll cnt[LEN];

int A(int n,int m){
    int a=1;
    while(m){
        a*=n--;
        m--;
    }
    return a;
}

int C(int n,int m){
    int c=A(n,m);
    while(m){
        c/=m--;
    }
    return c;
}

int main(){
//    freopen("D:/CbWorkspace/blue_bridge/k倍区间.txt","r",stdin);
    int i,j,n,k;
    ll ans=0;
    I("%d%d",&n,&k);
    FF(i,n){
        I("%d",&j);
        sum[i+1]=sum[i]+j;
    }
    cnt[0]=1;
    F(i,1,n+1){
        cnt[sum[i]%k]++;
    }
    FF(i,k){
        if(cnt[i]) ans+=cnt[i]*(cnt[i]-1)/2;    //C(n,2)
    }
    printf("%lld",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/TQCAI/p/8456397.html