Uoj Chen 394. [NOI2018] bubble sorting

Portal

Explanation:
There is a debuff in the exam room. It's a stupid question.

It is found that the equivalent is composed of at most two ascending sequences, and then it is equivalent to record fi, MXF {I, MX} fi, MX represents the number of schemes currently filled to the third position, and the maximum value is jjj. The next one is either larger than MX mxmxmx or the first one smaller than mxmxmxmxmx.

It is found that this is a sequence of parentheses. Being larger than mx is equivalent to adding some left parentheses, and then moving iii back is equivalent to adding right parentheses. You can quickly calculate the Cartland number.

For each fixed prefix, we enumerate what is filled in this bit (larger than the original one), and find that it is the sum of combined sequences, which can be calculated by O(1)O(1)O(1), with the total complexity O(n)O(n)O(n).

#include <bits/stdc++.h>
using namespace std;

const int RLEN=1<<18|1;
inline char nc() {
	static char ibuf[RLEN],*ib,*ob;
	(ib==ob) && (ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
	return (ib==ob) ? -1 : *ib++;
}
inline int rd() {
	char ch=nc(); int i=0,f=1;
	while(!isdigit(ch)) {if(ch=='-')f=-1; ch=nc();}
	while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=nc();}
	return i*f;	
}

const int N=1e6+3e5, mod=998244353;
inline int add(int x,int y) {return (x+y>=mod) ? (x+y-mod) : (x+y);}
inline int dec(int x,int y) {return (x-y<0) ? (x-y+mod) : (x-y);}
inline int mul(int x,int y) {return (long long)x*y%mod;}
inline int power(int a,int b,int rs=1) {for(;b;b>>=1,a=mul(a,a)) if(b&1) rs=mul(rs,a); return rs;}

struct Combin {
	int fac[N],ifac[N];
	Combin() {
		fac[0]=1;
		for(int i=1;i<N;i++) fac[i]=mul(fac[i-1],i);
		ifac[N-1]=power(fac[N-1],mod-2);
		for(int i=N-2;~i;i--) ifac[i]=mul(ifac[i+1],i+1);
	}
	inline int C(int a,int b) {return mul(fac[a],mul(ifac[b],ifac[a-b]));}
} C;

int n,mx,mn,p[N],c[N];
inline void solve() {
	n=rd(); mx=0; mn=1;
	for(int i=1;i<=n;i++) p[i]=rd(), c[i]=0;
	int ans=0, tag=1;
	for(int i=1;i<=n;i++) {
		int x=p[i]; c[x]=1;
		int lim=max(mx+1,x+1);
		if(lim<=n) {
			ans=add(ans,C.C(2*n-lim-i+1,n-i+1));
			if(lim<n) ans=dec(ans,C.C(2*n-lim-i+1,n-i+2));
		}
		if(x>mx) mx=x;
		else if(x!=mn) break;
		while(c[mn]) ++mn;
	} 
	printf("%d\n",ans);
}
int main() {
	for(int i=rd();i;i--) solve();
}

Posted by knashash on Thu, 19 Dec 2019 14:46:59 -0800