<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      康托展開

      康托展開是一種求一個排列在所有全排列中排名的算法,可以與Hash結合,將一個排列映射為整數

      康托展開

      先給出康托展開的公式
      定義\(0!=1\),對于一個\(1 \sim n\)的排列\(p=\{p_1, p_2,\cdots,p_n\}\),其排名

      \[r = \sum^{n}_{i=1} a_i(n-i)! \]

      其中,\(a_i\)是在\(p[i+1, n]\)中比\(p_i\)小的數的個數
      舉個例子,\(p=\{2, 5, 3, 4, 1\}\)
      那么,在\(2\)之前,有以\(1\)開頭的排列,個數為\(1 \times (5-1)!\)
      \(5\)之前,因為\(2\)已經取過了,所以只剩以\(1, 3, 4\)開頭的排列,個數為\(3 \times (5-2)!\)
      ..... 以此類推

      即枚舉到第\(i\)位時,后面的數形成的排列共有\((n-i)!\)個,而排在這個排列前面的就是第\(i\)位小于\(p_i\)的排列數,即\(a_i(n-i)!\)

      所以\(p\)的排名是 \(1 \times (5-1)! + 3 \times (5-2)!+1\times(5-3)!+1\times(5-4)!+0\times(5-5)! = 45\)

      所以每次暴力計算\(a_i\),就可以在\(O(n^2)\)時間計算出展開值

      再利用樹狀數組維護桶,并倒序枚舉,就可以優化到\(O(n\lg n)\)

      const int N = 1e6, P = 998244353;
      int n, p[N+5];
      ll fact[N+5]; // 在主函數中預處理階乘
      
      int c[N+5]; // 樹狀數組
      
      void add(int x, int k)
      {
      	for (; x <= n; x += lowbit(x))
      		c[x] += k;
      }
      
      int query(int x)
      {
      	int ans = 0;
      	for (; x >= 1; x -= lowbit(x))
      		ans += c[x];
      	return ans;
      }
      
      ll cantor(void)
      {
      	ll ans = 0;
      	for (int i = n; i >= 1; i--) {
      		int cnt = query(p[i] - 1); // 每次查詢[p[i] - 1, 1]的桶的和
      		add(p[i], 1);
      
      		ans += cnt * fact[n - i] % P;
      		ans %= P;
      	}
      	return ans;
      }
      

      逆康拓展開

      那么,如何通過一個排列的排名求出這個排列本身呢?
      如果我們想求排列的第一項,那么觀察上文的公式\(r = \sum_{i=1}^{n} a_i(n-i)!\)
      將第一項拆出來,\(r = a_1(n-1)! +\sum_{i=2}^{n}a_i(n-i)!\)

      觀察第二項,注意到

      \[\begin{align*} \sum_{i=2}^{n}a_i(n-i)! &\leq \sum_{i=2}^{n} (n-i) \times (n-i)! \\ &= \sum_{i=2}^{n}(n-i+1-1)\times(n-i)! \\ &= \sum_{i=2}^{n}(n-i+1)\times(n-i)! - \sum_{i=2}^{n}(n-i)! \\ &= \sum_{i=2}^{n}(n-i+1)! - \sum_{i=2}^{n}(n-i)! \\ &=(n-1)! - 1 \end{align*} \]

      因此,\(a_1 = \lfloor \frac{r}{(n-1)!} \rfloor\),通過枚舉,便可求出\(p_i\)
      然后,令\(r \leftarrow r \ \text{mod} \ (n-1)!\),循環求出每一位

      樸素算法

      bool vis[N+5];
      vector<int> decantor(ll rk)
      {
      	vector<int> c;
      	c.clear();
      
      	for (int i = n - 1; i >= 0; i--) {
      		int cnt = rk / fact[i];
      		rk %= fact[i];
      
      		for (int j = 1; j <= n; j++) {
      			if (!vis[j]) {
      				if (!cnt) {
      					c.push_back(j);
      					vis[j] = 1;
      					break;
      				}
      				cnt--;
      			}
      		}
      	}
      	return c;
      }
      

      例題
      P5367 【模板】康托展開
      CF501D Misha and Permutations Summation

      posted @ 2025-09-07 12:29  zhm0725  閱讀(21)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 久久夜色撩人精品国产av| 办公室强奷漂亮少妇同事| 亚洲成a人片在线观看日本| 亚洲国产日韩一区三区| 国产中文一区卡二区不卡| 欧美寡妇xxxx黑人猛交| 中文字幕无码免费不卡视频| 加勒比无码人妻东京热| 精品国产一区二区三区四区| 日韩av一区二区精品不卡| 日本欧美一区二区三区在线播放| 国产亚洲精品久久久久秋霞 | 秋霞AV鲁丝片一区二区| 久久人与动人物a级毛片| 大尺度国产一区二区视频| 全球成人中文在线| 亚洲香蕉伊综合在人在线| 亚洲精品中文字幕一二三| 色欲aⅴ亚洲情无码av蜜桃| 日韩大片看一区二区三区| 国产资源精品中文字幕| 丽水市| 精品国产乱弄九九99久久| 亚洲熟妇自偷自拍另类| 国产成人高清亚洲综合| 久久精品蜜芽亚洲国产av| 白嫩少妇激情无码| 大陆精大陆国产国语精品| 日韩av熟女人妻一区二| 亚洲红杏AV无码专区首页| 亚洲aⅴ男人的天堂在线观看| 亚洲精品一区二区二三区| 亚洲国产欧美在线人成| 好硬好湿好爽再深一点动态图视频| 艳妇乳肉豪妇荡乳在线观看| 制服丝袜中文字幕在线| 国产一区视频一区欧美| 国产99视频精品免费视频36| 国产成人精品亚洲资源| 国内精品久久人妻无码妲| 香蕉eeww99国产在线观看|