Problem:
Score : 800 points

Problem Statement

Given are integers N and X. For each integer k between 0 and X (inclusive), find the answer to the following question, then compute the sum of all those answers, modulo 998244353.

Let us repeat the following operation on the integer k. Operation: if the integer is currently odd, subtract 1 from it and divide it by 2; otherwise, divide it by 2 and add 2^{N-1} to it. How many operations need to be performed until k returns to its original value? (The answer is considered to be 0 if k never returns to its original value.)

Constraints

1 \leq N \leq 2\times 10^5

0 \leq X < 2^N

X is given in binary and has exactly N digits. (In case X has less than N digits, it is given with leading zeroes.)

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
X

Output

Print the sum of the answers to the questions for the integers between 0 and X (inclusive), modulo 998244353.

Sample Input 1

3
111

Sample Output 1

40

For example, for k=3, the operation changes k as follows: 1,0,4,6,7,3. Therefore the answer for k=3 is 6.

Sample Input 2

6
110101

Sample Output 2

616

Sample Input 3

30
001110011011011101010111011100

Sample Output 3

549320998

Solution in Rust (1.15.1) (judge verdict: Accepted)

use std::collections::BTreeMap;

const MOD: usize = 998244353;
fn main() {
    let s = std::io::stdin();
    let mut sc = Scanner(s.lock());
    let n: usize = sc.read();
    let mut s = sc
        .chars()
        .into_iter()
        .map(|c| c as usize - '0' as usize)
        .collect::<Vec<_>>();
    for i in 0..n {
        let c = s[i];
        s.push(c ^ 1);
    }

    let mut ks = vec![];
    for k in 1..(2 * n + 1) {
        if (2 * n) % k == 0 && n % k != 0 && k % 2 == 0 {
            ks.push(k);
        }
    }

    let mut ans = BTreeMap::new();
    for count in ks.into_iter() {
        let t = count / 2;
        let mut dp = vec![1, 0];
        for i in 0..t {
            let mut next = vec![0, 0];
            for under in 0..2 {
                for x in 0..2 {
                    if under == 1 {
                        next[under] += dp[under];
                        next[under] %= MOD;
                    } else if s[i] > x {
                        next[1] += dp[0];
                        next[1] %= MOD;
                    } else if s[i] == x {
                        next[0] += dp[0];
                        next[0] %= MOD;
                    }
                }
            }
            dp = next;
        }

        let mut ok = true;
        for i in 0..n {
            if i % count == i % t {
                if s[i] < s[i % t] {
                    ok = false;
                    break;
                } else if s[i] > s[i % t] {
                    break;
                }
            } else {
                if s[i] < s[i % t] ^ 1 {
                    ok = false;
                    break;
                } else if s[i] > s[i % t] ^ 1 {
                    break;
                }
            }
        }
        //        eprintln!("ok={} dp={:?}", ok, dp);
        let c = if ok { (dp[0] + dp[1]) } else { dp[1] };
        ans.insert(count, c);
    }

    //    eprintln!("{:?}", ans);

    let mut sum = 0;
    let keys = ans.keys().cloned().collect::<Vec<_>>();
    for key in keys.into_iter() {
        let c = *ans.get(&key).unwrap();
        sum += c * key;
        sum %= MOD;
        let mut cur = key * 2;
        while cur <= 2 * n {
            if let Some(a) = ans.get_mut(&cur) {
                *a = (*a + MOD - c) % MOD;
            }
            cur += key;
        }
    }

    println!("{}", sum);
}

// abcdef1 => 0abcdef
// abcdef0 => 1abcdef

pub struct Scanner<R>(R);

impl<R: std::io::Read> Scanner<R> {
    pub fn read<T: std::str::FromStr>(&mut self) -> T {
        use std::io::Read;
        let buf = self
            .0
            .by_ref()
            .bytes()
            .map(|b| b.unwrap())
            .skip_while(|&b| b == b' ' || b == b'\n')
            .take_while(|&b| b != b' ' && b != b'\n')
            .collect::<Vec<_>>();
        unsafe { std::str::from_utf8_unchecked(&buf) }
            .parse()
            .ok()
            .expect("Parse error.")
    }
    pub fn vec<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.read()).collect()
    }
    pub fn chars(&mut self) -> Vec<char> {
        self.read::<String>().chars().collect()
    }
}