首页 > 其他 > 详细

P5367 【模板】康托展开

时间:2019-08-14 14:02:05      阅读:75      评论:0      收藏:0      [点我收藏+]

我们的生活充满了未知与玄学

----------------------------------------

链接:P5367

----------------------------------------

康拓展开在此题就是求一个全排列的排名。

我觉得它适合用来优化内存,这样存全排列虽然还要展开,但是内存小啊。

----------------------------------------

康拓展开的原理

----------------------------------------

首先,我们要求出阶乘,不然会TLE,

然后根据公式计算就可以了。

‘但是我们怎么知道对于每一个数,他是当前没有用过的数的排名呢?

我们可以用一个树状数组来维护,每使用一个,就在相应下标下-1。

询问时用树状数组求出的区间和就是排名了

------------------------------------------

技术分享图片
 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 int t[1000001];
 5 int n;
 6 int mod=998244353;
 7 long long  f[1000001];
 8 int lowbit(int x){
 9     return x & -x;
10 }
11 void add(int x,int p){
12     while(p<=n){
13         t[p]+=x;
14         p+=lowbit(p);
15     }
16     return ;
17 }
18 int sum(int x){
19     int ans=0;
20     while(x){
21         ans+=t[x];
22         x-=lowbit(x);
23     }
24     return ans;
25 }
26 int now;
27 long long  anss;
28 int main(){
29     f[0]=1;
30     scanf("%d",&n);
31     for(int i=1;i<=n;++i)
32     f[i]=f[i-1]*i%mod;
33     for(int i=1;i<=n;++i)
34     add(1,i);
35     for(int i=n;i>=1;i--){
36         scanf("%d",&now);
37         anss+=(((sum(now)-1)*f[i-1])%mod)%mod;
38         anss%=mod;
39         add(-1,now);
40     }
41     printf("%lld\n",anss+1);
42     return 0;
43 } 
Ac

 

P5367 【模板】康托展开

原文:https://www.cnblogs.com/For-Miku/p/11351469.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!