Problem:
Problem F: Find the Multiples

You are given a sequence a0a1...aN-1 digits and a prime number Q. For each i ≤ j with ai ≠ 0, the subsequence aiai+1...aj 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 is a multiple of Q.

Input

The input consists of at most 50 datasets. Each dataset is represented by a line containing four integers N, S, W, and Q, separated by spaces, where 1 ≤ N ≤ 105, 1 ≤ S ≤ 109, 1 ≤ W ≤ 109, and Q is a prime number less than 108. The sequence a0...aN-1 of length N is generated by the following code, in which ai is written as a[i].

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 four zeros separated by spaces.

Output

For each dataset, output the answer in a line. You may assume that the answer is less than 230.

Sample Input

3 32 64 7
4 35 89 5
5 555 442 3
5 777 465 11
100000 666 701622763 65537
0 0 0 0

Output for the Sample Input

2
4
6
3
68530

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.

Solution in Rust (judge verdict: Accepted)

extern crate core;

use std::fmt;
use std::cmp::{Ordering, min, max};
use std::fmt::{Display, Error, Formatter};
use std::ops::{Index, IndexMut, Add, AddAssign, Sub, SubAssign, Mul, MulAssign};
use std::collections::{VecDeque, BinaryHeap, BTreeMap};
use std::f32::MAX;

fn show<T: Display>(vec: &Vec<T>) {
    if vec.is_empty() {
        println!("[]");
    }else {
        print!("[{}", vec[0]);
        for i in 1 .. vec.len() {
            print!(", {}", vec[i]);
        }
        println!("]");
    }
}
macro_rules! read_line{
    () => {{
        let mut line = String::new();
        std::io::stdin().read_line(&mut line).ok();
        line
    }};
    (delimiter: ' ') => {
        read_line!().split_whitespace().map(|x|x.to_string()).collect::<Vec<_>>()
    };
    (delimiter: $p:expr) => {
        read_line!().split($p).map(|x|x.to_string()).collect::<Vec<_>>()
    };
    (' ') => {
        read_line!(delimiter: ' ')
    };
    ($delimiter:expr) => {
        read_line!(delimiter: $delimiter)
    };
    (' '; $ty:ty) => {
        read_line!().split_whitespace().map(|x|x.parse::<$ty>().ok().unwrap()).collect::<Vec<$ty>>()
    };
    ($delimiter:expr; $ty:ty) => {
        read_line!($delimiter).into_iter().map(|x|x.parse::<$ty>().ok().unwrap()).collect::<Vec<$ty>>()
    };
}
macro_rules! let_all {
    ($($n:ident:$t:ty),*) => {
        let line = read_line!(delimiter: ' ');
        let mut iter = line.iter();
        $(let $n:$t = iter.next().unwrap().parse().ok().unwrap();)*
    };
}

fn make_sequence(n: usize, s: i64, w: i64) -> Vec<i64> {
    let mut result = Vec::with_capacity(n);
    let mut g = s;
    for _ in 0 .. n {
        result.push((g / 7) % 10);
        if g % 2 == 0 {
            g = g / 2;
        }else {
            g = (g / 2) ^ w;
        }
    }
    result
}
fn main() {
    loop {
        let_all!(n: usize, s: i64, w: i64, q: i64);
        if n == 0 && s == 0 && w == 0 && q == 0 {
            return;
        }
        let sequence = make_sequence(n, s, w);
        //show(&sequence);
        match q {
            2 | 5 => {
                let mut count = 0;
                let mut count_zero = 0;
                for i in 0 .. n {
                    if sequence[i] == 0 {
                        count_zero += 1;
                    }
                    if sequence[i] % q == 0 {
                        count += (i + 1 - count_zero) as i32;
                    }
                }
                println!("{}", count);
            }
            _ => {
                let mut map = BTreeMap::<i64, i32>::new();
                map.insert(0, 1);
                let mut digits = 1_i64;
                let mut prev = 0_i64;
                let mut count = 0;
                for i in 0 .. n {
                    prev = (prev +  digits * sequence[n - i - 1]) % q;
                    digits = (digits * 10) % q;
                    if let Some(c) = map.get_mut(&prev) {
                        if sequence[n - i - 1] != 0 {
                            count += *c;
                        }
                        *c += 1;
                        continue
                    }
                    map.insert(prev, 1);
                }
                println!("{}", count);
            }
        }
    }
}