Submission #64594847


Source Code Expand

#include <bits/stdc++.h>
using namespace std;
 
#define rng(i,a,b) for(int i=int(a);i<=int(b);i++)
#define rep(i,b) rng(i,0,b-1)
#define gnr(i,b,a) for(int i=int(b);i>=int(a);i--)
#define per(i,b) gnr(i,b-1,0)
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
#define bg begin()
#define ed end()
#define all(x) x.bg,x.ed
#define si(x) int(x.size())
template<class t> using vc=vector<t>;
template<class t> using vvc=vc<vc<t>>;
typedef long long ll;
using pii=pair<int,int>;
using vi=vc<int>;
using uint=unsigned;
using ull=unsigned long long;
using pil=pair<int,ll>;
using pli=pair<ll,int>;
using pll=pair<ll,ll>;
using t3=tuple<int,int,int>;
 
ll rand_int(ll l, ll r) { //[l, r]
	#ifdef LOCAL
	static mt19937_64 gen;
	#else
    static mt19937_64 gen(chrono::steady_clock::now().time_since_epoch().count());
    #endif
    return uniform_int_distribution<ll>(l, r)(gen);
}
 
 
template <uint MD> struct ModInt {
    using M = ModInt;
    const static M G;
    uint v;
    ModInt(ll _v = 0) { set_v(_v % MD + MD); }
    M& set_v(uint _v) {
        v = (_v < MD) ? _v : _v - MD;
        return *this;
    }
    explicit operator bool() const { return v != 0; }
    M operator-() const { return M() - *this; }
    M operator+(const M& r) const { return M().set_v(v + r.v); }
    M operator-(const M& r) const { return M().set_v(v + MD - r.v); }
    M operator*(const M& r) const { return M().set_v(ull(v) * r.v % MD); }
    M operator/(const M& r) const { return *this * r.inv(); }
    M& operator+=(const M& r) { return *this = *this + r; }
    M& operator-=(const M& r) { return *this = *this - r; }
    M& operator*=(const M& r) { return *this = *this * r; }
    M& operator/=(const M& r) { return *this = *this / r; }
    bool operator==(const M& r) const { return v == r.v; }
    M pow(ll n) const {
        M x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    M inv() const { return pow(MD - 2); }
    friend ostream& operator<<(ostream& os, const M& r) { return os << r.v; }
};
using Mint = ModInt<998244353>;
template<> const Mint Mint::G = Mint(3);

template <class Mint> void nft(bool type, vc<Mint>& a) {
    int n = int(a.size()), s = 0;
    while ((1 << s) < n) s++;
    assert(1 << s == n);

    static vc<Mint> ep, iep;
    while (int(ep.size()) <= s) {
        ep.push_back(Mint::G.pow(Mint(-1).v / (1 << ep.size())));
        iep.push_back(ep.back().inv());
    }
    vc<Mint> b(n);
    for (int i = 1; i <= s; i++) {
        int w = 1 << (s - i);
        Mint base = type ? iep[i] : ep[i], now = 1;
        for (int y = 0; y < n / 2; y += w) {
            for (int x = 0; x < w; x++) {
                auto l = a[y << 1 | x];
                auto r = now * a[y << 1 | x | w];
                b[y | x] = l + r;
                b[y | x | n >> 1] = l - r;
            }
            now *= base;
        }
        swap(a, b);
    }
}

template <class Mint> vc<Mint> multiply(const vc<Mint>& a, const vc<Mint>& b) {
    int n = int(a.size()), m = int(b.size());
    if (!n || !m) return {};
    if(n<30 || m<30){
        vc<Mint> ret(n+m-1);
        rep(i,n)rep(j,m)ret[i+j] += a[i]*b[j];
        return ret;
    }
    int lg = 0;
    while ((1 << lg) < n + m - 1) lg++;
    int z = 1 << lg;
    auto a2 = a, b2 = b;
    a2.resize(z);
    b2.resize(z);
    nft(false, a2);
    nft(false, b2);
    for (int i = 0; i < z; i++) a2[i] *= b2[i];
    nft(true, a2);
    a2.resize(n + m - 1);
    Mint iz = Mint(z).inv();
    for (int i = 0; i < n + m - 1; i++) a2[i] *= iz;
    return a2;
}
using t4 = tuple<int,int,int,int>;
using t5 = tuple<int,int,int,int,int>;

#define N_ 1001000
const int SZ = (1<<19);
int n, S1[N_], S2[N_];
char p[N_];
Mint D[N_][2], F[N_], invF[N_];
Mint R0[N_], R1[N_];
void DnC(int b, int e){
	if(b==e){
		rep(i,2) D[b][i] *= invF[S2[b]-S1[b]];
		return;
	}
	int m = (b+e)/2;

	DnC(b,m);

	rep(ck,2){
		vc<Mint> A(m-b+1), B(e-b+1);
		rng(i,b,m) A[S1[i]-S1[b]] += D[i][ck];

		int z = max(S2[m] - S1[m],0);
		rng(i,0,e-b) B[i] = F[i + z];
		auto C = multiply(A,B);

		rng(i,m+1,e){
			if(S2[i] < S1[i])continue;
			D[i][!ck] += C[S2[i] - S1[b] - z];
		}
	}

	DnC(m+1,e);

}
void Solve(){
	scanf("%d",&n);
	n*=2;
	F[0]=invF[0]=1;
	rng(i,1,n){
		F[i]=F[i-1]*i;
		invF[i]=invF[i-1]/i;
	}
	scanf("%s",p);
	D[0][1]=1;
	rep(i,n){
		S1[i+1]=S1[i];
		S2[i+1]=S2[i];
		if(p[i]=='B')S1[i+1]++;
		else S2[i+1]++;
	}
	DnC(0,n);
	printf("%d\n",(D[n][0]-D[n][1]).v);
}

int main(){
	//init();
	int TC=1;
	//scanf("%d",&TC);
	while(TC--){
		Solve();
	}

}

Submission Info

Submission Time
Task C - Strongly Connected
User ainta
Language C++ 20 (gcc 12.2)
Score 900
Code Size 4782 Byte
Status AC
Exec Time 1884 ms
Memory 47560 KiB

Compile Error

Main.cpp: In function ‘void Solve()’:
Main.cpp:159:14: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  159 |         scanf("%d",&n);
      |         ~~~~~^~~~~~~~~
Main.cpp:166:14: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  166 |         scanf("%s",p);
      |         ~~~~~^~~~~~~~

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 900 / 900
Status
AC × 3
AC × 41
Set Name Test Cases
Sample example_00.txt, example_01.txt, example_02.txt
All example_00.txt, example_01.txt, example_02.txt, test_00.txt, test_01.txt, test_02.txt, test_03.txt, test_04.txt, test_05.txt, test_06.txt, test_07.txt, test_08.txt, test_09.txt, test_10.txt, test_11.txt, test_12.txt, test_13.txt, test_14.txt, test_15.txt, test_16.txt, test_17.txt, test_18.txt, test_19.txt, test_20.txt, test_21.txt, test_22.txt, test_23.txt, test_24.txt, test_25.txt, test_26.txt, test_27.txt, test_28.txt, test_29.txt, test_30.txt, test_31.txt, test_32.txt, test_33.txt, test_34.txt, test_35.txt, test_36.txt, test_37.txt
Case Name Status Exec Time Memory
example_00.txt AC 8 ms 27276 KiB
example_01.txt AC 8 ms 27036 KiB
example_02.txt AC 8 ms 27152 KiB
test_00.txt AC 1874 ms 47400 KiB
test_01.txt AC 1874 ms 47504 KiB
test_02.txt AC 1879 ms 47448 KiB
test_03.txt AC 1878 ms 47444 KiB
test_04.txt AC 1878 ms 47560 KiB
test_05.txt AC 1877 ms 47504 KiB
test_06.txt AC 1878 ms 47468 KiB
test_07.txt AC 1876 ms 47492 KiB
test_08.txt AC 1875 ms 47456 KiB
test_09.txt AC 1876 ms 47500 KiB
test_10.txt AC 861 ms 37420 KiB
test_11.txt AC 912 ms 38660 KiB
test_12.txt AC 1868 ms 47048 KiB
test_13.txt AC 1822 ms 46252 KiB
test_14.txt AC 389 ms 32184 KiB
test_15.txt AC 193 ms 29624 KiB
test_16.txt AC 848 ms 37040 KiB
test_17.txt AC 22 ms 27472 KiB
test_18.txt AC 868 ms 37520 KiB
test_19.txt AC 384 ms 31860 KiB
test_20.txt AC 1877 ms 47456 KiB
test_21.txt AC 1882 ms 47560 KiB
test_22.txt AC 1875 ms 47468 KiB
test_23.txt AC 1884 ms 47448 KiB
test_24.txt AC 1878 ms 47468 KiB
test_25.txt AC 1881 ms 47472 KiB
test_26.txt AC 1879 ms 47448 KiB
test_27.txt AC 1884 ms 47464 KiB
test_28.txt AC 1878 ms 47320 KiB
test_29.txt AC 1882 ms 47468 KiB
test_30.txt AC 9 ms 27092 KiB
test_31.txt AC 8 ms 27276 KiB
test_32.txt AC 8 ms 27092 KiB
test_33.txt AC 8 ms 27092 KiB
test_34.txt AC 8 ms 27144 KiB
test_35.txt AC 8 ms 27228 KiB
test_36.txt AC 8 ms 27144 KiB
test_37.txt AC 8 ms 27152 KiB