康拓展开学习笔记
康拓展開
?
?
給出一個全排列,求他是第幾個全排列稱為康拓展開。
?
暴力康拓展開
對于一個全排列來說,從左往右第i位,有 n + 1 - i 種選擇。如果用變進制數(shù)表示的話,這一位就是 n + 1 - i 進制的數(shù),如果這一位選擇了第k種情況,那么對應(yīng)的這一位就是k。(k從0開始)
比如:1 4 5 2 3 6 變成變進制數(shù)就是(022000)
- 首位1 是6種選擇的第一種{1, 2, 3, 4, 5, 6},所以變?yōu)?。
- 次位4 是5種選擇的第三種{2, 3, 4, 5, 6},所以變?yōu)?。
- 次位5 是4種選擇的第三種{2, 3, 5, 6},所以變?yōu)?。
- 次位2 是3種選擇的第一種{2, 3, 6},所以變?yōu)?。
- 次位3 是2種選擇的第一種{3, 6},所以變?yōu)?。
- 末位6 是1種選擇的第一種{6},所以變?yōu)?。
我們發(fā)現(xiàn):第i位的值就是ai - 左邊比它小的數(shù)的個數(shù)- 1。
for (int i = 1; i <= n; ++i) {cin >> a[i];int x = a[i];for (int j = 1; j <= a[i]; ++j)x -= vis[j];vis[a[i]] = 1;a[i] = x - 1; }?之后把變進制數(shù)轉(zhuǎn)化成10進制就可以了
ll res = 0; for (int i = 1; i < n; ++i)res = (res + a[i]) * (n - i);最后的答案是 res + 1。
?
優(yōu)化
?
?
剛才的算法復(fù)雜度有O(N ^ 2),其實對于找左側(cè)比ai小的數(shù)的時候,用樹狀數(shù)組維護一下就可以在log的時間內(nèi)求出該值。
?
#include <bits/stdc++.h> using namespace std; #define forn(i, n) for (int i = 0; i < (n); i++) #define forab(i, a, b) for (int i = (a); i <= (b); i++) #define forba(i, b, a) for (int i = (b); i >= (a); i--) #define mset(a, n) memset(a, n, sizeof(a)) #define fast ios::sync_with_stdio(0), cin.tie(0), cout.tie(0) #define N 1000005 #define ll long long const int Q = 998244353; int a[N], c[N], n; ll res; inline int lowbit(int x) { return x & (-x); } void add(int x,int d) {while(x <= n){c[x] += d;x += lowbit(x);} } int sum(int x) {int s = 0;while(x){s += c[x];x -= lowbit(x);}return s; } int main() {fast;cin >> n;forab(i, 1, n){cin >> a[i];add(a[i], 1);if(i < n)res = ((res + a[i] - sum(a[i] - 1) - 1) * (n - i)) % Q;}cout << (res + 1) << endl; }
?(正在嘗試手推逆向康拓展開。。。
?
轉(zhuǎn)載于:https://www.cnblogs.com/zssst/p/11349750.html
總結(jié)
- 上一篇: 无法登录谷歌账号,提示次浏览器或应用可能
- 下一篇: win10+tensorflow CPU