[Method summary] Cantor Cantor Expansion Expand

[Method summary] Cantor Cantor Expansion Expand

First, on expansion Cantor

1. What is Cantor Expand

Arranged to determine the location of any given one of integers 1 to n is from 1 to n in the full array.
Algorithm to solve this problem is called Cantor started.
For example:
\ (n-4 = \) , the sequence = {a \ (1,3,4,2 \) }, then the whole arrangement positions in a 1 to 4 for the first four.

2. Expand the realization of the principle Cantor

To know the sequence came in a few, we need to know how many bit prior to sequence a.
We calculated according to the above chestnuts:
1. There are a number smaller than 1 0, with a \ (0 \ times (4-1) = 0 \!) Permutations.
2 is smaller than the number 3 has two, but one has been occupied, and therefore can be used only a number, a total of \ (1 \ times (3-1) ! = 2 \) permutations.
3. Number 4 has smaller than 3, but 3 is filled, the only one available, a total of \ (1 \ times (2-1) ! = 1 \) permutations.
4. The ratio of the number 2 has a small, but the whole is occupied, so the available sort of \ (0 \ times (1-1) ! = 0 \) column.
Until now, we know that there are three arranged in front of a sequence, a sequence thus ranked 4th.
Formula:
\ [!! K_1 POS = (. 1-n-) + K_2 (-n-2) + ... + K_n (NN) \!]
Use the tree array optimization statistics, the total complexity is \ (O (NlogN ) \) .

Second, the specific embodiment

1. Templates

P5367 [template] Cantor Expand

#include<bits/stdc++.h>
#define ll long long
#define N 1000010
#define MOD 998244353
using namespace std;
int n,t[N];
ll fac[N],ans;
inline void calc_factorial(int n){
    fac[1]=1;
    for(int i=2;i<=n;i++)
        fac[i]=i*fac[i-1]%MOD;
}
inline int lowbit(int x){
    return x&(-x);
}
inline void modify(int x,int k){
    while(x<=n){
        t[x]+=k;
        x+=lowbit(x);
    }
}
inline ll query(int x){
    ll res=0;
    while(x>0){
        res+=t[x];
        x-=lowbit(x);
    }
    return res;
}
int main()
{
    scanf("%d",&n);
    calc_factorial(n);
    for(int i=1;i<=n;i++) modify(i,1);
    for(int i=1,num;i<=n;i++){
        scanf("%d",&num);
        ans=(ans+((query(num)-1)*fac[n-i])%MOD)%MOD;
        //core code: restnum*(n-i)!
        modify(num,-1);
    }
    printf("%lld",ans+1);
    return 0;
}

Guess you like

Origin www.cnblogs.com/cyanigence-oi/p/11732120.html