P5367 【模板】康託展開

纯粹的發表於2024-04-05

原題連結

題解

1.一眼數位dp, 康託是誰?不認識,在每一位確保小於的時候可以任意取
2.階乘一開始就要放好
3.在遍歷到後面幾位的時候,可能前面幾位用過了比x小的樹,所以我們要知道小於x且沒被用過的個數,這就是區間查詢加單點修改,樹狀陣列比較方便
4.樹狀陣列的空間複雜度比較小,每個點就對應且只對應一個區間

code

#include<bits/stdc++.h>
#define lowbit(x)  ((x)&(-x))
const int mod=998244353;
int tree[1000008]={0};
using namespace std;
int n;
int jc[1000005]={1,1};
void cal()
{
    for(int i=2;i<=n;i++) jc[i]=jc[i-1]*i%mod;
}

int query(int x)
{
    int sum=0;
    while(x)
    {
        sum+=tree[x];
        sum%=mod;
        x-=lowbit(x);
    }
    return sum;
}

void update(int x,int val)
{
    while(x<=n)
    {
        tree[x]+=val;
        tree[x]%=mod;
        x+=lowbit(x);
    }
}

int main()
{
    cin>>n;
    cal();
    for(int i=1;i<=n;i++) update(i,1);
    int ans=0;
    for(int i=n;i>=1;i--)
    {
        int x;
        cin>>x;

        int small=query(x-1)%mod;
        ans+=small*jc[i-1]%mod;
        ans%=mod;
        update(x,-1);
    }
    cout<<ans+1;
    return 0;
}

相關文章