kuangbinOJ B Lucky Sequence (hash大发)

来源:互联网 发布:便携式数据采集器pt800 编辑:程序博客网 时间:2024/05/17 08:00

题意:

给出一个序列,问子序列是k的倍数的个数。

题解:

用hash存0-n的前缀和,然后根据这个式子 (sum[j]-sum[i])%k=0 变形 (sum[j]%k+k)%k=(sum[i]%k+k)%k ,这样做为了保证负数也通过。然后只要查找是否目前hash中能找到多少个(sum[j]%k+k)%k。

#include<iostream>#include<math.h>#include<stdio.h>#include<algorithm>#include<string.h>#include<vector>#include<queue>#include<map>#include<set>using namespace std;#define B(x) (1<<(x))typedef long long ll;void cmax(int& a,int b){if(b>a)a=b;}void cmin(int& a,int b){if(b<a)a=b;}void lcmax(ll& a,ll b){if(b>a)a=b;}void lcmin(ll& a,ll b){if(b<a)a=b;}const int oo=0x3f3f3f3f;const int MOD=1000007;const int maxn=1000007;struct HASH_MAP{    ll state[maxn],num[maxn];    int next[maxn],head[maxn],tol;    void Init(){        memset(head,-1,sizeof head);        tol=0;    }    ll check(ll s){        ll ans=0;        int h=(s%maxn+maxn)%maxn;        for(int i=head[h];i!=-1;i=next[i]){            if(s==state[i]){                num[i]++;                ans+=num[i];            }        }        return ans;    }    void ins(ll s){        int h=(s%maxn+maxn)%maxn;        for(int i=head[h];i!=-1;i=next[i]){            if(s==state[i])return;        }        state[tol]=s;        num[tol]=0;        next[tol]=head[h];        head[h]=tol++;    }}mat;int main(){    //freopen("E:\\read.txt","r",stdin);    int T,n,k,a;    scanf("%d",&T);    while(T--){        mat.Init();        scanf("%d %d",&n,&k);        ll sum=0;        ll ans=0;        mat.ins(0);        for(int i=1;i<=n;i++){            scanf("%d",&a);            sum+=a;            ans+=mat.check((sum%k+k)%k);            mat.ins((sum%k+k)%k);        }        printf("%lld\n",ans);    }    return 0;}




0 0
原创粉丝点击