QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#108895 | #6513. Expression 3 | RiceShower# | TL | 2569ms | 144216kb | C++23 | 11.4kb | 2023-05-26 21:25:06 | 2023-05-26 21:25:10 |
Judging History
answer
// 从未在意的名字永远不会被提起 - 雪葉/鹤见江野
/*
+
++
+++
++++
+++++
++++++
+++++++
++++++++
+++++++++
++++++++++
+++++++++++
++++++++++++
+++++++++++++
++++++++++++++
+++++++++++++++
++++++++++++++++
+++++++++++++++++
++++++++++++++++++
+ +++++++++++++++++
+ ++++++++++++++ ++
+ +++++++++++++ ++
+ ++++++++++++ ++
+ +++++++++++ ++
+ ++++++++++ ++
+ +++++++++ ++
+ ++++++++ ++
+ +++++++++++++++++
+ +++++++++++++++++
+ ++++++++++++++
+ +++++++++++
+ ++++++++
+ +++++
+ ++
+ +
+ +
+ ++
+ +++
+ ++++
+ +++++
+ +++++
+ +++++
+ +++++
+ + +++++
+ +++ +++++
+ ++ ++ +++++
+ ++ ++ +++++
+ ++ + ++ +++++
+++ +++ +++++++
++ ++ ++ ++++++
++++++++ +++++++++++ +++ +++ ++++++++ ++++++++
+++++++++ +++++++++++++ +++ +++ +++ +++ +++ +++
+++ +++ +++ +++ +++ +++ +++ ++++++ +++ +++
+++ +++ +++ +++ +++ +++ +++ +++ +++ +++
+++ +++ +++ +++ +++ ++ +++ ++ ++++++ +++ +++
+++++++++ +++ +++ +++ +++ ++ +++ ++ +++ +++ +++ ++
++++++++ +++ +++ +++ +++++ +++++ ++++++++ +++++++++++
*/
// #define DEBUG
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#include <assert.h>
#include <set>
#define od(x) printf("%d",x)
#define odb(x) printf("%d ",x)
#define odl(x) printf("%d\n",x)
#define odp(x,y) printf("%d %d\n",x,y)
#define ol(x) puts("")
#define old(x) printf("%lld",x)
#define oldb(x) printf("%lld ",x)
#define oldl(x) printf("%lld\n",x)
#define oldp(x,y) printf("%lld %lld\n",x,y)
#define rg(x) for(int i=1;i<=(x);i++){
#define rg_(i,x) for(int i=1;i<=(x);i++){
#define fe(u) for(int i=h[u];i;i=e[i].nxt){int v=e[i].v;
#define gr }
#define rrg(x) for(int i=0;i<(x);i++)
#define rdln(a) a[i]=read();
#define rdln0(a,x) rrg(x) rdln(a) gr
#define rdln1(a,x) rg(x) rdln(a) gr
template<typename T>
void print(T x){}
template<>
void print<int>(int x){od(x);}
template<>
void print<const int>(const int x){od(x);}
template<>
void print<long long>(long long x){old(x);}
template<>
void print<const long long>(const long long x){old(x);}
template<>
void print<char>(char x){putchar(x);}
template<>
void print<const char>(const char x){putchar(x);}
template<>
void print<double>(double x){printf("%.12lf",x);}
template<typename T,typename... qwq>
void print(T x,qwq ...args)
{
print(x);
print(args...);
}
#ifdef DEBUG
template<typename T>
void debug(T x){}
template<>
void debug<int>(int x){od(x);}
template<>
void debug<const int>(const int x){od(x);}
template<>
void debug<long long>(long long x){old(x);}
template<>
void debug<const long long>(const long long x){old(x);}
template<>
void debug<char>(char x){putchar(x);}
template<>
void debug<const char>(const char x){putchar(x);}
template<>
void debug<double>(double x){printf("%.12lf",x);}
template<typename T,typename... qwq>
void debug(T x,qwq ...args)
{
debug(x);
debug(args...);
}
#define dflush fflush
#else
#define dflush(...) 0
template<typename T,typename... qwq>
void debug(T x,qwq ...args)
{
}
#endif
#define int long long
#define newe(n) struct Edge{int v,w,nxt;}e[2*n+5];\
typedef int arr[n+5];\
arr h;\
int cnt=1;\
inline void addedge(int u,int v,int w){e[cnt]=(Edge){v,w,h[u]};h[u]=cnt++;}
#define mgs int fa[1<<22],sz[1<<22];\
inline int f(int x){return x==fa[x]?x:fa[x]=f(fa[x]);}\
inline int uf(int x,int y)\
{\
int fx=f(x),fy=f(y);\
if(fx==fy)return 0;\
if(sz[fx]>sz[fy])fx^=fy^=fx^=fy;\
fa[fx]=fy,sz[fy]+=sz[fx];\
return 1;\
}
inline int read()
{
int num=0,f=1;char c=getchar();
while(c<48||c>57){if(c=='-')f=-1;c=getchar();}
while(c>47&&c<58)num=num*10+(c^48),c=getchar();
return num*f;
}
inline int re1d()
{
char c=getchar();
while(c<48||c>49)c=getchar();
return c&1;
}
inline int min(int a,int b){return a>b?b:a;}
inline int max(int a,int b){return a<b?b:a;}
#define L(i, j, k) for(int i = (j); i <= (k); ++i)
#define R(i, j, k) for(int i = (j); i >= (k); --i)
#define ll long long
#define vi vector <int>
#define sz(a) ((int) (a).size())
using namespace std;
const int mod = 998244353, _G = 3, N = (1 << 21), inv2 = (mod + 1) / 2;
#define add(a, b) (a + b >= mod ? a + b - mod : a + b)
#define dec(a, b) (a < b ? a - b + mod : a - b)
int qpow(int x, int y = mod - 2) {
int res = 1;
for(; y; x = (ll) x * x % mod, y >>= 1) if(y & 1) res = (ll) res * x % mod;
return res;
}
int fac[N], ifac[N], inv[N];
void init(int x) {
fac[0] = ifac[0] = inv[1] = 1;
L(i, 2, x) inv[i] = (ll) inv[mod % i] * (mod - mod / i) % mod;
L(i, 1, x) fac[i] = (ll) fac[i - 1] * i % mod, ifac[i] = (ll) ifac[i - 1] * inv[i] % mod;
}
int C(int x, int y) {
return y < 0 || x < y ? 0 : (ll) fac[x] * ifac[y] % mod * ifac[x - y] % mod;
}
int rt[N], Lim;
void Pinit(int x) {
for(Lim = 1; Lim <= x; Lim <<= 1) ;
for(int i = 1; i < Lim; i <<= 1) {
int sG = qpow (_G, (mod - 1) / (i << 1));
rt[i] = 1;
L(j, i + 1, i * 2 - 1) rt[j] = (ll) rt[j - 1] * sG % mod;
}
}
struct poly {
vector<int> a;
int size() { return sz(a); }
int & operator [] (int x) { return a[x]; }
int v(int x) { return x < 0 || x >= sz(a) ? 0 : a[x]; }
void clear() { vector<int> ().swap(a); }
void rs(int x = 0) { a.resize(x); }
poly (int n = 0) { rs(n); }
poly (vector<int> o) { a = o; }
poly (const poly &o) { a = o.a; }
poly Rs(int x = 0) { vi res = a; res.resize(x); return res; }
inline void dif() {
int n = sz(a);
for (int l = n >> 1; l >= 1; l >>= 1)
for(int j = 0; j < n; j += l << 1)
for(int k = 0, *w = rt + l; k < l; k++, w++) {
int x = a[j + k], y = a[j + k + l];
a[j + k] = add(x, y);
a[j + k + l] = (ll) * w * dec(x, y) % mod;
}
}
void dit () {
int n = sz(a);
for(int i = 2; i <= n; i <<= 1)
for(int j = 0, l = (i >> 1); j < n; j += i)
for(int k = 0, *w = rt + l; k < l; k++, w++) {
int pa = a[j + k], pb = (ll) a[j + k + l] * *w % mod;
a[j + k] = add(pa, pb), a[j + k + l] = dec(pa, pb);
}
reverse(a.begin() + 1, a.end());
for(int i = 0, iv = qpow(n); i < n; i++) a[i] = (ll) a[i] * iv % mod;
}
friend poly operator * (poly aa, poly bb) {
if(!sz(aa) || !sz(bb)) return {};
int lim, all = sz(aa) + sz(bb) - 1;
for(lim = 1; lim < all; lim <<= 1);
aa.rs(lim), bb.rs(lim), aa.dif(), bb.dif();
L(i, 0, lim - 1) aa[i] = (ll) aa[i] * bb[i] % mod;
aa.dit(), aa.a.resize(all);
return aa;
}
poly Inv() {
poly res, f, g;
res.rs(1), res[0] = qpow(a[0]);
for(int m = 1, pn; m < sz(a); m <<= 1) {
pn = m << 1, f = res, g.rs(pn), f.rs(pn);
for(int i = 0; i < pn; i++) g[i] = (*this).v(i);
f.dif(), g.dif();
for(int i = 0; i < pn; i++) g[i] = (ll) f[i] * g[i] % mod;
g.dit();
for(int i = 0; i < m; i++) g[i] = 0;
g.dif();
for(int i = 0; i < pn; i++) g[i] = (ll) f[i] * g[i] % mod;
g.dit(), res.rs(pn);
for(int i = m; i < min(pn, sz(a)); i++) res[i] = (mod - g[i]) % mod;
}
return res.rs(sz(a)), res;
}
poly Shift (int x) {
poly zm (sz(a) + x);
L(i, max(-x, 0), sz(a) - 1) zm[i + x] = a[i];
return zm;
}
friend poly operator * (poly aa, int bb) {
poly res(sz(aa));
L(i, 0, sz(aa) - 1) res[i] = (ll) aa[i] * bb % mod;
return res;
}
friend poly operator + (poly aa, poly bb) {
vector<int> res(max(sz(aa), sz(bb)));
L(i, 0, sz(res) - 1) res[i] = add(aa.v(i), bb.v(i));
return poly(res);
}
friend poly operator - (poly aa, poly bb) {
vector<int> res(max(sz(aa), sz(bb)));
L(i, 0, sz(res) - 1) res[i] = dec(aa.v(i), bb.v(i));
return poly(res);
}
poly & operator += (poly o) {
rs(max(sz(a), sz(o)));
L(i, 0, sz(a) - 1) (a[i] += o.v(i)) %= mod;
return (*this);
}
poly & operator -= (poly o) {
rs(max(sz(a), sz(o)));
L(i, 0, sz(a) - 1) (a[i] += mod - o.v(i)) %= mod;
return (*this);
}
poly & operator *= (poly o) {
return (*this) = (*this) * o;
}
poly Integ() {
if(!sz(a)) return poly();
poly res(sz(a) + 1);
L(i, 1, sz(a)) res[i] = (ll) a[i - 1] * inv[i] % mod;
return res;
}
poly Deriv() {
if(!sz(a)) return poly();
poly res(sz(a) - 1);
L(i, 1, sz(a) - 1) res[i - 1] = (ll) a[i] * i % mod;
return res;
}
poly Ln() {
poly g = ((*this).Inv() * (*this).Deriv()).Integ();
return g.rs(sz(a)), g;
}
poly Exp() {
poly res(1), f;
res[0] = 1;
for(int m = 1, pn; m < sz(a); m <<= 1) {
pn = min(m << 1, sz(a)), f.rs(pn), res.rs(pn);
for(int i = 0; i < pn; i++) f[i] = (*this).v(i);
f -= res.Ln(), (f[0] += 1) %= mod, res *= f, res.rs(pn);
}
return res.rs(sz(a)), res;
}
poly pow(int x, int rx = -1) { // x : the power % mod; rx : the power % (mod - 1)
if(rx == -1) rx = x;
int cnt = 0;
while (a[cnt] == 0 && cnt < sz(a)) cnt += 1;
poly res = (*this);
L(i, cnt, sz(a) - 1) res[i - cnt] = res[i];
L(i, sz(a) - cnt, sz(a) - 1) res[i] = 0;
int c = res[0], w = qpow (res[0]);
L(i, 0, sz(res) - 1) res[i] = (ll) res[i] * w % mod;
res = res.Ln();
L(i, 0, sz(res) - 1) res[i] = (ll) res[i] * x % mod;
res = res.Exp();
c = qpow (c, rx);
L(i, 0, sz(res) - 1) res[i] = (ll) res[i] * c % mod;
if((ll) cnt * x > sz(a)) L(i, 0, sz(a) - 1) res[i] = 0;
else if(cnt) {
R(i, sz(a) - cnt * x - 1, 0) res[i + cnt * x] = res[i];
L(i, 0, cnt * x - 1) res[i] = 0;
}
return res;
}
poly sqrt(int rt = 1) {
poly res(1), f;
res[0] = rt;
for(int m = 1, pn; m < sz(a); m <<= 1) {
pn = min(m << 1, sz(a)), f.rs(pn);
for(int i = 0; i < pn; i++) f[i] = (*this).v(i);
f += res * res, f.rs(pn), res.rs(pn), res = f * res.Inv(), res.rs(pn);
for(int i = 0; i < pn; i++) res[i] = (ll) res[i] * inv2 % mod;
}
return res;
}
void Rev() {
reverse(a.begin(), a.end());
}
friend pair < poly, poly > div (poly f, poly g) { /* f / g = first, f % g = second */
f.rs(max(sz(f), sz(g))), f.Rev(), g.Rev();
int n = sz(f), m = sz(g);
poly A = g.Rs(n - m + 1).Inv(), t;
A *= f.Rs(n - m + 1), A.rs(n - m + 1), A.Rev(), g.Rev(), f.Rev(), t = f - A * g, t.rs(m - 1);
return make_pair(A, t);
}
} ;
int n, k;
// poly G;
int d[1000005];
#define inf 0x3f3f3f3f3f3f3f3f
#define gcd std::__gcd
#define p mod
void mne(int &a,int b){if(a>b)a=b;}
int a[200003];
char s[200003];
int res[1234567];
poly sgn[1234567],val[1234567];
void build(int o,int l,int r)
{
if(l==r)
{
sgn[o].a={mod-l-2*(s[l]=='-'),1};
val[o].a={mod-l,1};
return;
}
int m=l+r>>1;
build(o<<1,l,m);
build(o<<1|1,m+1,r);
sgn[o]=sgn[o<<1]*sgn[o<<1|1];
val[o]=val[o<<1]*val[o<<1|1];
}
void solve(int o,int l,int r,poly x)
{
if(l==r)
{
res[l]=x[0];
return;
}
int m=l+r>>1;
solve(o<<1,l,m,div(x,val[o<<1]).second);
solve(o<<1|1,m+1,r,div((x*sgn[o<<1]),val[o<<1|1]).second);
}
signed main()
{
int n=read();
init(5e5*2+5),Pinit(5e5*2+5);
for(int i=1; i<=n; ++i) a[i]=read();
scanf("%s",s+1);
int ans=0;
build(1,1,n);
poly x;x.a={1};
solve(1,1,n,x);
for(int i=1; i<=n; ++i)
{
int sum=res[i];
// for(int j=i-1; j>0; --j)
// sum=sum*((i-j+p)-2*(s[j]=='-'))%p;
ans=(ans+a[i]*fac[n-1]%p*ifac[i-1]%p*sum)%p;
}
printf("%lld\n",ans);
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 63ms
memory: 92516kb
input:
4 9 1 4 1 -+-
output:
46
result:
ok 1 number(s): "46"
Test #2:
score: 0
Accepted
time: 84ms
memory: 92484kb
input:
5 1 2 3 4 5 +-+-
output:
998244313
result:
ok 1 number(s): "998244313"
Test #3:
score: 0
Accepted
time: 2569ms
memory: 144216kb
input:
100000 664815434 205025136 871445392 797947979 379688564 336946672 231295524 401655676 526374414 670533644 156882283 372427821 700299596 166140732 677498490 44858761 185182210 559696133 813911251 842364231 681916958 114039865 222372111 784286397 437994571 152137641 650875922 613727135 209302742 5321...
output:
178167352
result:
ok 1 number(s): "178167352"
Test #4:
score: -100
Time Limit Exceeded
input:
200000 109044620 745578941 396599814 756923982 940933214 875346257 378089839 792684563 491924893 782192923 208569108 421583135 814903710 690275542 15773609 364566266 12890134 661702679 640270667 615999192 13352194 325560419 385152885 265008089 570536451 282429805 331946208 255056541 813809151 150995...