【数论模拟】

【模拟+数论】

随机栈

https://codeforces.com/gym/105158/submit
image

思路

把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;
}
posted @ 2025-04-29 10:45  White_ink  阅读(11)  评论(0)    收藏  举报