题意:有一个由1到k组成的序列,最小是1 2 … k,最大是 k k-1 … 1,给出n的计算方式,n = s0 * (k - 1)! + s1 * (k - 2)! +… + sk-1 * 0!,

给出s1…sk,输出序列里第n大的序列。

析:我们先看第一数,如果第一个数是2,那么它前面至少有(k-1)!个排列,然后1开头肯定比2要小,同理,再考虑第二个数,在考虑再二数时,

要注意把已经搞定的数去掉,所以我们用线段树进行单点更新,当然也可以用二分+数状数组。

代码如下:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#include <sstream>
#define debug() puts("++++");
#define gcd(a, b) __gcd(a, b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std; typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const LL LNF = 1e16;
const double inf = 0x3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 5e4 + 10;
const int mod = 1e9 + 7;
const int dr[] = {-1, 0, 1, 0};
const int dc[] = {0, 1, 0, -1};
const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline bool is_in(int r, int c){
return r >= 0 && r < n && c >= 0 && c < m;
}
int sum[maxn<<2]; void push_up(int rt){ sum[rt] = sum[rt<<1] + sum[rt<<1|1]; } void build(int l, int r, int rt){
if(l == r){
sum[rt] = 1; return ;
}
int m = l+r >> 1;
build(lson);
build(rson);
push_up(rt);
} int query(int x, int l, int r, int rt){
if(l == r){
sum[rt] = 0; return l;
}
int m = l+r >> 1;
int ans;
if(sum[rt<<1] >= x) ans = query(x, lson);
else ans = query(x-sum[rt<<1], rson);
push_up(rt);
return ans;
} int main(){
int T; cin >> T;
while(T--){
scanf("%d", &n);
build(1, n, 1);
for(int i = 0; i < n; ++i){
if(i) putchar(' ');
scanf("%d", &m);
printf("%d", query(m + 1, 1, n, 1));
}
printf("\n");
}
return 0;
}

  

UVaLive 11525 Permutation (线段树)的更多相关文章

  1. bnu 51636 Squared Permutation 线段树

    Squared Permutation Time Limit: 6000ms Memory Limit: 262144KB 64-bit integer IO format: %lld      Ja ...

  2. UVALive - 4108 SKYLINE[线段树]

    UVALive - 4108 SKYLINE Time Limit: 3000MS     64bit IO Format: %lld & %llu Submit Status uDebug ...

  3. UVA 11525 Permutation (树状数组+YY)

    题意:给你k个数Si,然后给你一个等式   H= ∑  Si ∗ (K − i)!  (i=(1->k)且0 ≤ Si ≤ K − i). 叫你求出第H个全排列 其实这是一个康托展开:X=a[n ...

  4. UVALive - 3938 (线段树,区间查询)

    思路:详细分析见训练指南.注意可能答案的起点在左区间,终点在右区间 AC代码 #include <stdio.h> #include <algorithm> using nam ...

  5. Permutation UVA - 11525(值域树状数组,树状数组区间第k大(离线),log方,log)(值域线段树第k大)

    Permutation UVA - 11525 看康托展开 题目给出的式子(n=s[1]*(k-1)!+s[2]*(k-2)!+...+s[k]*0!)非常像逆康托展开(将n个数的所有排列按字典序排序 ...

  6. UVA 11525 Permutation ——(线段树,脑筋急转弯)

    只要注意到对于譬如:S1*(k-1)! 因为后面k-1个数字的全排列个数刚好是(k-1)!,那么第一个数字就是没有取过的数字的第(S1+1)个即可.取走这个数字以后这个数字就不能再用了,依次类推即可得 ...

  7. CF798E. Mike and code of a permutation [拓扑排序 线段树]

    CF798E. Mike and code of a permutation 题意: 排列p,编码了一个序列a.对于每个i,找到第一个\(p_j > p_i\)并且未被标记的j,标记这个j并\( ...

  8. MemSQL Start[c]UP 2.0 - Round 1 F - Permutation 思维+线段树维护hash值

    F - Permutation 思路:对于当前的值x, 只需要知道x + k, x - k这两个值是否出现在其左右两侧,又因为每个值只有一个, 所以可以转换成,x+k, x-k在到x所在位置的时候是否 ...

  9. 2017西安区域赛A / UVALive - 8512 线段树维护线性基合并

    题意:给定\(a[1...n]\),\(Q\)次询问求\(A[L...R]\)的异或组合再或上\(K\)的最大值 本题是2017的西安区域赛A题,了解线性基之后你会发现这根本就是套路题.. 只要用线段 ...

随机推荐

  1. mini2440移植uboot 2011.03(上)

    参考博文: <u-boot-2011.03在mini2440/micro2440上的移植> 本来我想移植最新版的uboot,但是移植却不太成功,所以先模仿他人的例子重新执行一遍,对uboo ...

  2. poj 1144 Network 【求一个网络的割点的个数 矩阵建图+模板应用】

    题目地址:http://poj.org/problem?id=1144 题目:输入一个n,代表有n个节点(如果n==0就结束程序运行). 在当下n的这一组数据,可能会有若干行数据,每行先输入一个节点a ...

  3. Struts2 遇到的问题汇总

    1.报错如下信息: org.apache.jasper.JasperException: The Struts dispatcher cannot be found. This is usually ...

  4. Java之泛型深解

    泛型的内容确实很多,在上一篇Java之泛型浅解讲到了一些常用的泛型,但是还远远不够,上一篇的内容比较容易理解,这一篇我自己觉得更加难理解一些,因此,我还得想办法让它更加接地气更加容易理解,方便我和源宝 ...

  5. Linux tar.gz 、zip、rar 解压 压缩命令

    tar -c: 建立压缩档案 -x:解压 -t:查看内容 -r:向压缩归档文件末尾追加文件 -u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个 ...

  6. Eclipse_常用技巧_02_使用Eclipse进行源码分析

    1.分析java类和接口的继承关系 具体做法: 在代码区中选择需要的类和接口定义,然后右击,选择“Open Type Hiberarchy”,可以在“Hiberarchy View”中看到继承关系 快 ...

  7. Oracle_Exception_01_The Network Adapter could not establish the connection

    1.IP错误或端口错误. 在设置URL时错误,例如 url="jdbc:oracle:thin:@192.168.1.11:1521:mas" 数据库服务器不正确:ping 服务器 ...

  8. FFMPEG基于内存的转码实例——输入输出视频均在内存

    我在6月份写了篇文章<FFMPEG基于内存的转码实例>,讲如何把视频转码后放到内存,然后通过网络发送出去.但该文章只完成了一半,即输入的数据依然是从磁盘文件中读取.在实际应用中,有很多数据 ...

  9. 【VS】VS开发中遇到的问题的总结

    1.  VS中经常会出现无法解析的外部符号,还有LINK ERROR 2019等 这类问题如果检查代码没有错误,很大概率就是lib文件错误.调试程序找出问题函数,再找出问题函数使用到的lib文件,在项 ...

  10. oracle sql性能

    1.查询所对象相关的表?V$LOCK, V$LOCKED_OBJECT, V$SESSION, V$SQLAREA, V$PROCESS ;查询锁的表的方法:SELECT S.SID SESSION_ ...