【数论模拟】
【模拟+数论】
随机栈
https://codeforces.com/gym/105158/submit

思路
把p和q分开考虑:
(1)p:模拟一遍取数过程,每次都取当前最小值(优先队列)
p初始为1 每次*个数
(2)q:每次遇到-1就*一次当前数的个数
代码
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef pair<int,int> PII;
typedef long long ll;
ll abss(ll a){return a>0?a:-a;}
ll max_(ll a,ll b){return a>b?a:b;}
ll min_(ll a,ll b){return a<b?a:b;}
bool cmpll(ll a,ll b){return a>b;}
const ll MOD=998244353;
ll qmi(ll a,ll k,ll p){
ll ans=1;
while(k){
if(k&1) ans=ans*a%p;
k>>=1;
a=a*a%p;
}
return ans;
}
int n;
void solve(){
cin>>n;
vector<int> a(2*n+1,0);
map<int,int> ma;
ll p=1;
for(int i=1;i<=2*n;i++){
cin>>a[i];
}
priority_queue<int,vector<int>,greater<int>> qq;
int maxx=-1e9;
for(int i=1;i<=2*n;i++){
if(a[i]>-1){
qq.push(a[i]);
ma[a[i]]++;
}
else if(a[i]==-1){
int tt=qq.top();
//cout<<tt<<endl;
//cout<<maxx<<endl;
if(tt<maxx){
p=0;
break;
}
qq.pop();
maxx=tt;
p=p*(ll)ma[tt]%MOD;
ma[tt]--;
}
}
ll cnt=0;
ll q=1;
for(int i=1;i<=2*n;i++){
if(a[i]>-1) cnt++;
else if(a[i]==-1){
q=(q*cnt)%MOD;
cnt--;
}
}
ll ans=p*qmi(q,MOD-2,MOD)%MOD;
cout<<ans<<endl;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int T=1;
//cin>>T;
while(T--) solve();
return 0;
}

浙公网安备 33010602011771号