首页 > 其他分享 >P8376 [APIO2022] 排列

P8376 [APIO2022] 排列

时间:2023-06-08 21:46:20浏览次数:54  
标签:cnt 排列 ++ push long P8376 pop APIO2022 front

一种比较容易写的构造方案

考虑直接二进制拆分,发现在原排列的基础上,在开头填上更大的数,方案数+1,在末尾上填上更大的数,方案数*2,

直接按照填数从小到大顺序填入,长度为 logk + popcount(k),期望得分91分

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 vector <int> construct_permutation(long long k)
 6 {
 7     stack <int> s;
 8     for (long long x = k; x != 1; x >>= 1) s.push(x & 1);
 9     deque <int> q;
10     for (int cnt = 0; !s.empty() ; s.pop())
11     {
12         q.push_back(cnt++);
13         if (s.top()) q.push_front(cnt++);
14     }
15     vector <int> ans;
16     while (!q.empty()) ans.push_back(q.front()), q.pop_front();
17     return ans;
18 }

发现如果已经有两次以上的+1操作,可以把原排列的前两位与前三位之间放入更大的数,方案数+3

可以把 *2 +1 *2 +1 变成 *2 *2 +3 ,可以通过该题

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 vector <int> construct_permutation(long long k)
 6 {
 7     stack <int> s;
 8     for (long long x = k; x != 1; x >>= 1) s.push(x & 1);
 9 
10     deque <int> q;
11     bool pd = false;
12     for (int cnt = 0, s1 = 0; !s.empty(); s.pop())
13     {
14         if (s1 > 3 && pd && s.top()) // *2 +1 *2 +1 -> *2 *2 +3 
15         { // (now) *2 +1
16             q.pop_front(); --cnt; // del +1
17             q.push_back(cnt++); // add *2
18             int x = q.front(); q.pop_front();
19             int y = q.front(); q.pop_front();
20             q.push_front(cnt++); // +3
21             q.push_front(y);
22             q.push_front(x);
23             pd = false;
24             continue;
25         }
26         q.push_back(cnt++);
27         if (s.top()) q.push_front(cnt++), s1++, pd = true;
28         else pd = false;
29     }
30 
31     vector <int> ans;
32     while (!q.empty()) ans.push_back(q.front()), q.pop_front();
33     return ans;
34 }

 

标签:cnt,排列,++,push,long,P8376,pop,APIO2022,front
From: https://www.cnblogs.com/mayber/p/17467740.html

相关文章

  • 【python练习】排列
    题目给定一个整数n,将数字1∼n排成一排,将会有很多种排列方法。现在,请你按照字典序将所有的排列方法输出。输入格式共一行,包含一个整数n。输出格式按字典序输出所有排列方案,每个方案占一行。代码n=int(input())path=[0foriinrange(n)]used=[Falseforiinrange(n)]de......
  • wukong引擎源码分析之索引——part 1 倒排列表本质是有序数组存储
    searcher.IndexDocument(0,types.DocumentIndexData{Content:"此次百度收购将成中国互联网最大并购"})engine.go中的源码实现://将文档加入索引////输入参数://docId标识文档编号,必须唯一//data见DocumentIndexData注释////注意://1.这个函数是线程安全......
  • 排列算法问题
    |类循环排列#treeDFSdefloop_permutation(arr,depth,path,result):ifdepth==len(arr):result.append(list(path))returnforninarr:path.append(n)loop_permutation(arr,depth+1,path,result)path.pop(......
  • 全排列
    生成全排列的三种方法该函数生成全排列时需要注意原数组本身需要排好序,并且没有重复元素,否则生成的结果会有重复。voidPermutation(intk,inta[],intlen){ if(k==len){ for(inti=0;i<len;i++){ cout<<a[i]<<''; } cout<<endl; return; } for(inti=k;i<len;i++)......
  • 排列组合的实现Cmn,Amn
    递归方法:publicclassCombination{/***计算从m个元素中选n个元素的组合数Cmn*@paramm总共有m个元素*@paramn从中选n个元素*@return组合数Cmn的值*/publicstaticintCmn(intm,intn){if(n==0||n==m){......
  • 2023-05-22:给定一个长度为 n 的字符串 s ,其中 s[i] 是: D 意味着减少; I 意味着增加。
    2023-05-22:给定一个长度为n的字符串s,其中s[i]是:D意味着减少;I意味着增加。有效排列是对有n+1个在[0,n]范围内的整数的一个排列perm,使得对所有的i:如果s[i]=='D',那么perm[i]>perm[i+1],以及;如果s[i]=='I',那么perm[i]<perm[i+1]。返回有效排列......
  • 集合排列、分割
    目录1.全排列(去重)2.子集3.集合分割1.全排列(去重)voiddfs(constvector<int>&nums,intpos,vector<vector<int>>&result,vector<int>&cur){if(pos==nums.size()){result.push_back(cur);return;}for......
  • 标准库中的生成器函数——用于重新排列元素的生成器函数
         1注意,itertools.groupby假定输入的可迭代对象要使用分组标准排序;即使不排序,至少也要使用指定的标准分组各个元素。  1#itertools.groupby函数的用法2importitertools3456k1=list(itertools.groupby('LLLLAAGGG'))7print('k1:',k......
  • 全排列去重
    全排列去重的前提要求是目标集合必须是经过排序的。在目标集合排序的前提下,第i位变换数字前后,如果是相同的数字,就会产生重复的排列。注意:第i位变换的意思是i位本身的变换,而不是i与i-1的比较。题目链接代码如下:voiddfs(constvector<int>&nums,intpos,vector<vector<int>......
  • 2023-05-16:给你一个 严格升序排列 的正整数数组 arr 和一个整数 k 。 请你找到这个数
    2023-05-16:给你一个严格升序排列的正整数数组arr和一个整数k。请你找到这个数组里第k个缺失的正整数。输入:arr=[2,3,4,7,11],k=5。输出:9。答案2023-05-16:大体步骤如下:1.初始化左指针l为0,右指针r为数组长度减一,定义中间指针m和find(找到第k个正整数前的下标位置),......