Time Limit: 3000 Ms memory limit: 65536kb
Description you are given a sequence a [0] a [1]... A [N-1] of digits and a prime number Q. for each I <= J with a [I]! = 0, the subsequence A [I] a [I + 1]... A [J] can be read as a decimal representation of a positive integer. subsequences with leading zeros are not considered. your task is to count the number of pairs (I, j) such that the corresponding subsequence Modulo q is R. input the input consists of at most 10 datasets. each dataset is represented by a line containing four integers n, S, W, Q, and R, separated by spaces, where 1 <= n <= 10 ^ 5, 1 <= S <= 10 ^ 9, 1 <= W <= 10 ^ 9, Q is a prime number less than 10 ^ 9 and 0 <= r <q. the sequence a [0]... A [N-1] of length N is generated by the following code.
Int G = s;
For (INT I = 0; I <n; I ++ ){
A [I] = (G/7) % 10;
If (G % 2 = 0) {G = (G/2 );}
Else {G = (G/2) ^ W ;}
}
Note: The operators/, %, and ^ are the integer division, the modulo, And the bitwise exclusiveor, respectively. the above code is meant to be a random number generator. the intended solution does not rely on the way how the sequence is generated. the end of the input is indicated by a line containing five zeros separated by spaces. output for each dataset, output the answer in a line.
Sample Input
3 32 64 7 0
4 35 89 5 0
5 555 442 3 0
5 777 465 11 0
100000 666 701622763 65537
0 0 0 0 0 0
Sample output
2
4
6
3
68530
Hint in the first dataset, the sequence is 421. we can find two multiples of Q = 7, namely, 42 and 21. in the second dataset, the sequence is 5052, from which we can find 5, 50,505, and 5 being the multiples of Q = 5. notice that we don't count 0 or 05 since they are not a valid representation of positive integers. also notice that we count 5 twice, because it occurs twice in different positions. in the third and fourth datasets, the sequences are 95073 and 12221, respectively.
Theme
Returns a string of decimal numbers, and calculates the number of substrings represented by the numeric modulo number P as R.
Ideas
Assume that a substring is X [I] X [I + 1]... X [J], then the modulo p value is (X [I] * 10 ^ (J-I) + X [I + 1] * 10 ^ (j-i-1) +... + X [J] * 10 ^ 0) % P. If f [N] is used to represent (10 ^ N) % P, T [N] indicates the value of the last n modulo p of the original string. Then, X [I] X [I + 1]... X [J] % P = R is equivalent to T [I] = (T [J-1] + R * 10 ^ (J-1 )) % P = (T [J-1] + R * f [J-1]) % P, (A/B) % C = (a % (B * C )), in this way, the number that meets the requirements in the number starting with I is the number of J that meets the formula (j> = I ). The number of map or hash records can be used, and m [x] indicates the number of J that conform to (t [J] + R * f [J]) % P = x.
Practice
Generate a numeric string based on the method given by the question, obtain f [N] Through preprocessing, process T [N] from the right to the left, and add M [T [N] to the answer. update M [(T [N] + R * f [N]) % P.
Description
Special processing is required when the prime number in the question is 2 or 5, because 10 can be divisible by 2 or 5, and the remainder cannot be obtained in the form of 10 power. In this case, you only need to keep counting the number of substrings whose last modulo p is R from the high position, because the remainder of a number except 2 or 5 is equal to the last modulo 2 or 5.
The first digit cannot be 0. Therefore, you must note that the answer can be updated only when the current digit is not 0.
#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<map>using namespace std;const int N=100005;long long a[N];long long f[N];void init(int n,long long s,long long w){long long g=s;for (int i=1; i<=n; i++){a[i]=(g/7)%10;if (g%2==0) g=g/2; else g=(g/2)^w;}}int main(){int n,i;long long s,w,q,r;long long x,y,ans;while (scanf("%d%lld%lld%lld%lld",&n,&s,&w,&q,&r)==5){if (n==0 && s==0 && w==0 && q==0 && r==0) break;init(n,s,w); ans=0;if (q==2 || q==5){s=0;for (i=1; i<=n; i++){if (a[i]!=0) s++;if (a[i]%q==r) ans+=s;}}if (q!=2 && q!=5){f[n]=1;for (i=n-1; i>=1; i--) f[i]=(f[i+1]*10)%q;map<int,int> m;m[r]=1;x=0;for (i=n; i>=1; i--){x=(x+a[i]*f[i])%q;if (a[i]!=0)ans+=m[x];m[(r*f[i-1]+x)%q]++;}}printf("%lld\n",ans);}return 0;}
Number Theory (same remainder + hash)