码迷,mamicode.com
首页 > 其他好文 > 详细

康拓展开和逆康拓展开

时间:2019-08-09 23:59:21      阅读:241      评论:0      收藏:0      [点我收藏+]

标签:ref   --   href   https   scanf   include   bre   复杂度   set   

康拓展开和逆康拓展开

康拓展开模板题

复杂度O(\(n^2\))的会tle(看数据就知道了)(虽然某题解说可以,不知道是不是后期加强了数据

然而我还是写了O(\(n^2\))的

#include <cstdio>

typedef long long LL;
LL f[1000010];
const LL mod = 998244353;
int a[1000010], b[1000010];
int main() {
    f[0] = 1;
    for(int i = 1; i < 1000005; i++) f[i] = f[i-1] * i % mod;
    int n;
    while(~scanf("%d", &n)) {
        for(int i = 0; i < n; i++) {
            scanf("%d", &a[i]);
            b[a[i]] = 0;
        }
        LL ans = 1, cnt;
        for(int i = 0; i < n; i++) {
            cnt = 0;
            for(int j = 1; j < a[i]; j++) {
                if(b[j] == 0) cnt++;
            }
            b[a[i]] = 1;
            ans = ans % mod + cnt * f[n - i - 1];
        }
        printf("%lld\n", ans % mod);
    }
    return 0;
}

下面这个是树状数组实现的,复杂度O(nlogn) (能过)

#include <cstdio>

typedef long long LL;
LL f[1000010];
const LL mod = 998244353;
int a[1000010], n, bit[1000010];
void add(int i, int x) {
    while(i <= n) {
        bit[i] += x;
        i += i & (-i);
    }
}
int query(int i) {
    int res = 0;
    while(i > 0) {
        res += bit[i];
        i -= i & (-i);
    }
    return res;
}
int main() {
    f[0] = 1;
    for(int i = 1; i < 1000005; i++) f[i] = f[i-1] * i % mod;
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
        add(a[i], 1);
    }
    LL ans = 1, cnt;
    for(int i = 1; i <= n; i++) {
        add(a[i], -1);
        cnt = query(a[i]);
        ans = ans % mod + cnt * f[n - i];
    }
    printf("%lld\n", ans % mod);
    return 0;
}

逆康拓展开O(\(n^2\))

#include <cstdio>
#include <cstring>

int main() {
    int n, k, f[15], b[15];
    f[0] = 1;
    for(int i = 1; i < 11; i++) f[i] = f[i-1] * i;
    while(~scanf("%d %d", &n, &k)) {
        memset(b, 0, sizeof(b));
        k--;
        for(int i = n - 1; i >= 0; i--) {
            int ans = k / f[i], cnt = 0;
            for(int j = 1; j <= n; j++) {
                if(cnt == ans && b[j] == 0) {
                    b[j] = 1;
                    printf("%d ", j);
                    break;
                }
                if(b[j] == 0) cnt++;
            }
            k = k % f[i];
        }
        printf("\n");
    }
    return 0;
}

复杂度更低的我还不会 呜呜我好菜

逆康拓展开题目

康拓展开和逆康拓展开

标签:ref   --   href   https   scanf   include   bre   复杂度   set   

原文地址:https://www.cnblogs.com/fanshhh/p/11329750.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!