zoukankan      html  css  js  c++  java
  • 康拓展开和逆康拓展开

    康拓展开和逆康拓展开

    康拓展开模板题

    复杂度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
    ", 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
    ", 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("
    ");
        }
        return 0;
    }
    
    

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

    逆康拓展开题目

  • 相关阅读:
    Java:多线程<一>
    Java:Exception
    Java: 内部类
    Ubuntu安装jdk
    ubuntu搜狗拼音安装
    录音-树莓派USB摄像头话筒
    leetcode 最小栈
    leetcode 编辑距离 动态规划
    leetcode 最小覆盖字串
    leetcode 最长上升子序列 动态规划
  • 原文地址:https://www.cnblogs.com/fanshhh/p/11329750.html
Copyright © 2011-2022 走看看