[11] NOIP17 improve simulation training series

Topic Link

Progression

Title Description

Give you a length \ (N \) in the sequence of positive integers, if a continuous sequence, promoter sequence and can be \ (K \) is divisible, then depending on this sub-sequence legitimate, find the original sequence, including how many legitimate the continuous sequence? For a sequence of length 8, \ (K =. 4 \) case: 2, 1, 2, 1, 1, 2, 1, 2. It answers to 6, sequence is position 1-> position 8, a 2> 4,2-> 7,3-> 5,4> 6,5> 7.

Input formats:

First line: \ (T \) , represents the number of data sets
for each group of data:
The first line: the number 2, \ (K \) , \ (N \)
the second row: \ (N \) number, this sequence represents the

Output formats:

Total T lines, each line represents a number of answers

Sample input:

2
7 3
1 2 3
4 8
2 1 2 1 1 2 1 2

Sample output:

0
6

data range:

100% data satisfies
\ (. 1 <= T <= 20 is \)
\ (. 1 <= N <= 50000 \)
\ (. 1 <= K <= 1000000 \)
\ (each number sequence <= 1000000000 \)
30 % data satisfies
\ (. 1 <= T <= 10 \)
\ (. 1 <= N, K <= 1000 \)

time limit:

1S

Space limitations:

256M

prompt:

remove!!!

answer

And be contiguous subsequence \ (K \) number divisible?
\ (n ^ 2 \) violence? \ (. 1 <= N <= 50000 \) , seemingly not pass.
If we look at some of the maintenance properties of some numbers before this bunch of numbers, each adding a number to update some of these properties. (Do not ask how I think, would have thought dp or greedy, then I kept thinking thought)
every time you add a number, just find this number in front of some of this points to a consecutive sequence of numbers can be \ ( K \) number divisible.
So all we need is the value before the current number and suffix.
We can use an array \ (kk [i] \) represents the die and the suffix \ (K \) in the sense of extension and \ (I \) number, a number is added every time when a determined number \ ( X \) the number of added plus \ (X \) post-mold \ (K \) is 0, so that \ (ANS \) plus \ (kk [x] \) on the line.
But we found update to add a new number \ (kk \) time required is \ (O (n) \) , and
here we use a \ (SUM \) , every time you add a new number\ (SUM \) to add this number, then the \ (kk [i] \) on the die and suffixes \ (K \) in the sense of extension and \ (i + sum% K \ ) number.
Then to add a new number \ (kk \) becomes when \ (kk [(a-sum )% K] ++ \) a. ( \ (A \) as the new number)
to do the time complexity seems to be \ (O (n) \) is.
On the code:

#include<bits/stdc++.h>
using namespace std;
int t,k,n,a[50009];
int sum;
int ans;
int kk[1000009];
int main(){
    scanf("%d",&t);
    while(t--){
        memset(kk,0,sizeof(kk));
        ans=sum=0;
        scanf("%d%d",&k,&n);
        for(int j=1;j<=n;j++){
            scanf("%d",&a[j]);
            a[j]%=k;
            ans+=kk[(k-((a[j]+sum)%k))%k];//(a[j]+sum)%k可能是0,所以k-(a[j]+sum)%k可能为k,所以最后还要%k
            sum+=a[j];
            sum%=k;
            kk[(a[j]-sum+k)%k]++;
            if(a[j]%k==0) ans++;//要注意序列里只有一个点的时候也要加到$ans$里去
        }
        printf("%d\n",ans);
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/linjiale/p/11308931.html