Problem:
Score : 500 points

Problem Statement

There are 2N squares arranged from left to right. You are given a string of length 2N representing the color of each of the squares.

The color of the i-th square from the left is black if the i-th character of S is B, and white if that character is W.

You will perform the following operation exactly N times: choose two distinct squares, then invert the colors of these squares and the squares between them. Here, to invert the color of a square is to make it white if it is black, and vice versa.

Throughout this process, you cannot choose the same square twice or more. That is, each square has to be chosen exactly once.

Find the number of ways to make all the squares white at the end of the process, modulo 10^9+7.

Two ways to make the squares white are considered different if and only if there exists i (1 \leq i \leq N) such that the pair of the squares chosen in the i-th operation is different.

Constraints

1 \leq N \leq 10^5

|S| = 2N

Each character of S is B or W.

Input

Input is given from Standard Input in the following format:

N
S

Output

Print the number of ways to make all the squares white at the end of the process, modulo 10^9+7. If there are no such ways, print 0.

Sample Input 1

2
BWWB

Sample Output 1

4

There are four ways to make all the squares white, as follows:

Choose Squares 1, 3 in the first operation, and choose Squares 2, 4 in the second operation.

Choose Squares 2, 4 in the first operation, and choose Squares 1, 3 in the second operation.

Choose Squares 1, 4 in the first operation, and choose Squares 2, 3 in the second operation.

Choose Squares 2, 3 in the first operation, and choose Squares 1, 4 in the second operation.

Sample Input 2

4
BWBBWWWB

Sample Output 2

288

Sample Input 3

5
WWWWWWWWWW

Sample Output 3

0

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

/*------------------------------------------------------------------*/
/*------------------------- begin template -------------------------*/
/*------------------------------------------------------------------*/

// ref: tanakh <https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8>
// diff: using Parser
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut parser = Parser::from_str($s);
        input_inner!{parser, $($r)*}
    };
    (parser = $parser:ident, $($r:tt)*) => {
        input_inner!{$parser, $($r)*}
    };
    (new_stdin_parser = $parser:ident, $($r:tt)*) => {
        let stdin = std::io::stdin();
        let reader = std::io::BufReader::new(stdin.lock());
        let mut $parser = Parser::new(reader);
        input_inner!{$parser, $($r)*}
    };
    ($($r:tt)*) => {
        input!{new_stdin_parser = parser, $($r)*}
    };
}

macro_rules! input_inner {
    ($parser:ident) => {};
    ($parser:ident, ) => {};
    ($parser:ident, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($parser, $t);
        input_inner!{$parser $($r)*}
    };
}

macro_rules! read_value {
    ($parser:ident, ( $($t:tt),* )) => {
        ( $(read_value!($parser, $t)),* )
    };
    ($parser:ident, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($parser, $t)).collect::<Vec<_>>()
    };
    ($parser:ident, chars) => {
        read_value!($parser, String).chars().collect::<Vec<char>>()
    };
    ($parser:ident, char_) => {
        read_value!($parser, String).chars().collect::<Vec<char>>()[0]
    };
    ($parser:ident, usize1) => {
        read_value!($parser, usize) - 1
    };
    ($parser:ident, i64_) => {
        $parser.fast_i64()
    };
    ($parser:ident, usize_) => {
        $parser.fast_i64() as usize
    };
    ($parser:ident, usize1_) => {
        ($parser.fast_i64() - 1) as usize
    };
    ($parser:ident, $t:ty) => {
        $parser.next::<$t>().expect("Parse error")
    };
}

use std::io;
use std::io::BufRead;
use std::str;

// ref: tatsuya6502 <https://qiita.com/tatsuya6502/items/cd448486f7ef7b5b8c7e>
// ref: wariuni <https://qiita.com/tatsuya6502/items/cd448486f7ef7b5b8c7e#comment-7040a5ae96305e884eb9>
// diff: using std::io::BufRead::fill_buf()
pub struct Parser<R> {
    pub reader: R,
    buf: Vec<u8>,
    pos: usize,
}

impl Parser<io::Empty> {
    pub fn from_str(s: &str) -> Parser<io::Empty> {
        Parser {
            reader: io::empty(),
            buf: s.as_bytes().to_vec(),
            pos: 0,
        }
    }
}

impl<R: BufRead> Parser<R> {
    pub fn new(reader: R) -> Parser<R> {
        Parser {
            reader: reader,
            buf: vec![],
            pos: 0,
        }
    }
    pub fn update_buf(&mut self) {
        self.buf.clear();
        self.pos = 0;
        loop {
            let (len, complete) = {
                let buf2 = self.reader.fill_buf().unwrap();
                self.buf.extend_from_slice(buf2);
                let len = buf2.len();
                (len, buf2[len - 1] <= 0x20)
            };
            self.reader.consume(len);
            if complete {
                break;
            }
        }
    }
    pub fn next<T: str::FromStr>(&mut self) -> Result<T, T::Err> {
        loop {
            let mut begin = self.pos;
            while begin < self.buf.len() && (self.buf[begin] <= 0x20) {
                begin += 1;
            }
            let mut end = begin;
            while end < self.buf.len() && (self.buf[end] > 0x20) {
                end += 1;
            }
            if begin != self.buf.len() {
                self.pos = end;
                return unsafe { str::from_utf8_unchecked(&self.buf[begin..end]) }.parse::<T>();
            } else {
                self.update_buf();
            }
        }
    }
    pub fn fast_i64(&mut self) -> i64 {
        loop {
            let mut begin = self.pos;
            while begin < self.buf.len() && (self.buf[begin] <= 0x20) {
                begin += 1;
            }
            if begin == self.buf.len() {
                self.update_buf();
                continue;
            }
            let mut res = 0;
            let (is_positive, mut end) = match self.buf[begin] {
                b'+' => (true, begin + 1),
                b'-' => (false, begin + 1),
                _ => (true, begin),
            };
            while end < self.buf.len() && (self.buf[end] > 0x20) {
                res = res * 10 + (self.buf[end] as i64 - '0' as i64);
                end += 1;
            }
            if begin != self.buf.len() {
                self.pos = end;
                return if is_positive { res } else { -res };
            } else {
                self.update_buf();
            }
        }
    }
}

#[allow(unused_imports)]
use std::cmp::*;
use std::marker::PhantomData;
use std::ops::*;

pub trait ModP {
    fn as_u64() -> u64;
}

#[allow(non_camel_case_types)]
#[derive(Clone, Copy, Debug)]
pub struct Mod_1_000_000_007();
impl ModP for Mod_1_000_000_007 {
    fn as_u64() -> u64 {
        1_000_000_007
    }
}

#[allow(non_camel_case_types)]
#[derive(Clone, Copy, Debug)]
pub struct Mod_998_244_353();
impl ModP for Mod_998_244_353 {
    fn as_u64() -> u64 {
        998_244_353
    }
}

#[derive(Clone, Copy, PartialEq, Debug)]
pub struct Modular<P: ModP + Copy>(u32, PhantomData<P>);

impl<P: ModP + Copy> Modular<P> {
    pub fn new(x: u32) -> Modular<P> {
        Modular((x as u64 % P::as_u64()) as u32, PhantomData)
    }
    pub fn pow(self, n: u64) -> Modular<P> {
        if n == 0 {
            return Modular(1, PhantomData);
        }
        let t = self.pow(n / 2);
        if n % 2 == 0 {
            t * t
        } else {
            t * t * self
        }
    }
    pub fn as_u32(self) -> u32 {
        self.0
    }
}

impl<P: ModP + Copy> Add for Modular<P> {
    type Output = Self;
    fn add(self, rhs: Self) -> Self::Output {
        let t = (self.0 + rhs.0) as u64;
        let u = if t < P::as_u64() { t } else { t - P::as_u64() };
        Modular(u as u32, PhantomData)
    }
}

impl<P: ModP + Copy> AddAssign for Modular<P> {
    fn add_assign(&mut self, rhs: Self) {
        *self = *self + rhs;
    }
}

impl<P: ModP + Copy> Sub for Modular<P> {
    type Output = Self;
    fn sub(self, rhs: Self) -> Self::Output {
        let t = if self.0 >= rhs.0 {
            self.0 as u64 - rhs.0 as u64
        } else {
            self.0 as u64 + P::as_u64() - rhs.0 as u64
        };
        assert!(t < P::as_u64());
        Modular(t as u32, PhantomData)
    }
}

impl<P: ModP + Copy> SubAssign for Modular<P> {
    fn sub_assign(&mut self, rhs: Self) {
        *self = *self - rhs;
    }
}

impl<P: ModP + Copy> Neg for Modular<P> {
    type Output = Modular<P>;
    fn neg(self) -> Modular<P> {
        Modular((P::as_u64() - self.0 as u64) as u32, PhantomData)
    }
}

impl<P: ModP + Copy> Mul for Modular<P> {
    type Output = Self;
    fn mul(self, rhs: Self) -> Self::Output {
        Modular(
            ((self.0 as u64 % P::as_u64()) * (rhs.0 as u64 % P::as_u64()) % P::as_u64()) as u32,
            PhantomData,
        )
    }
}

impl<P: ModP + Copy> MulAssign for Modular<P> {
    fn mul_assign(&mut self, rhs: Self) {
        *self = *self * rhs;
    }
}

impl<P: ModP + Copy> Div for Modular<P> {
    type Output = Self;
    fn div(self, rhs: Self) -> Self::Output {
        if rhs.0 == 0 {
            loop {}
        }
        assert!(rhs.0 != 0);
        self * rhs.pow(P::as_u64() - 2)
    }
}

impl<P: ModP + Copy> DivAssign for Modular<P> {
    fn div_assign(&mut self, rhs: Self) {
        *self = *self / rhs;
    }
}

pub fn gen_fact_table<P: ModP + Copy>(n: usize) -> Vec<Modular<P>> {
    let mut res = vec![Modular::<P>::new(1); n + 1];
    for i in 0..n {
        res[i + 1] = res[i] * Modular::<P>::new((i + 1) as u32);
    }
    res
}

pub fn gen_inv_table<P: ModP + Copy>(n: usize) -> Vec<Modular<P>> {
    let mut res = vec![Modular::<P>::new(0); n + 1];
    res[1] = Modular::<P>::new(1);
    for i in 2..n + 1 {
        res[i] =
            -res[P::as_u64() as usize % i] * Modular::<P>::new((P::as_u64() / i as u64) as u32);
    }
    res
}

fn main() {
    input! {
        new_stdin_parser = parser,
    }
    let res = solve(&mut parser);
    print!("{}", res);
}

/*------------------------------------------------------------------*/
/*-------------------------- end template --------------------------*/
/*------------------------------------------------------------------*/

type Mod = Modular<Mod_1_000_000_007>;

use std::fmt::Write;
fn solve<R: BufRead>(parser: &mut Parser<R>) -> String {
    let mut buf = String::new();
    input! {
        parser = parser,
        n: usize,
        s: chars,
    }
    let mut m = 0;
    let mut res = Mod::new(1);
    for &c in &s {
        match c {
            'B' => {
                if m % 2 == 0 {
                    m += 1;
                } else {
                    res *= Mod::new(m);
                    if m == 0 {
                        writeln!(buf, "0");
                        return buf;
                    }
                    m -= 1;
                }
            }
            'W' => {
                if m % 2 == 0 {
                    res *= Mod::new(m);
                    if m == 0 {
                        writeln!(buf, "0");
                        return buf;
                    }
                    m -= 1;
                } else {
                    m += 1;
                }
            }
            _ => panic!(),
        }
    }
    if m != 0 {
        writeln!(buf, "0");
        return buf;
    }
    for i in 1..n + 1 {
        res *= Mod::new(i as u32);
    }
    writeln!(buf, "{}", res.as_u32());
    buf
}