1. 程式人生 > >k倍區間

k倍區間

取余 %d sum efi mem bsp urn pla hide

用前綴和來求區間和,然後用一個二重循環窮舉,但是因為問題規模為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\n",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;
}

k倍區間