P5367 【模板】康托展开

原题链接

题解

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;
}

posted @   纯粹的  阅读(7)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示