ZYB's Premutation

 

 Memory Limit: 131072/131072 K (Java/Others)
问题描述
ZYBZYB有一个排列PP,但他只记得PP中每个前缀区间的逆序对数,现在他要求你还原这个排列.

(i,j)(i < j)(i,j)(i<j)被称为一对逆序对当且仅当A_i>A_jA​i​​>A​j​​
输入描述
第一行一个整数TT表示数据组数。

接下来每组数据:

第一行一个正整数NN,描述排列的长度.

第二行NN个正整数A_iA​i​​,描述前缀区间[1,i][1,i]的逆序对数.

数据保证合法.

1 \leq T \leq 51≤T≤5,1 \leq N \leq 500001≤N≤50000
输出描述
TT行每行NN个整数表示答案的排列.
输入样例
1
3
0 1 2
输出样例
3 1 2

 题解:设f_if​i​​是第ii个前缀的逆序对数,p_ip​i​​是第ii个位置上的数,则f_i-f_{i-1}f​i​​−f​i−1​​是ii前面比p_ip​i​​大的数的个数.我们考虑倒着做,当我们处理完ii后面的数,第ii个数就是剩下的数中第f_i-f_{i-1}+1f​i​​−f​i−1​​+1大的数,用线段树和树状数组可以轻松地求出当前第kk个是11的位置,复杂度O(N \log N)O(NlogN).

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 5e4 + ;
long long arr[maxn],b[maxn]; #define lowbit(x) ((x)&(-x)) struct BinaryIndexTree
{
int val[maxn],sz; void init(int sz){
this->sz=sz;
memset(val , , sizeof(int)*(sz+));
} void updata(int pos ,int key){
while(pos<=sz){
val[pos]+=key;
pos+=lowbit(pos);
}
} int prefixsum(int pos){
int res=;
while(pos>){
res+=val[pos];
pos-=lowbit(pos);
}
return res;
} int query(int l,int r){
return prefixsum(r)-prefixsum(l-);
} //找到第一个大于等于k的位置返回
//若不存在,返回-1
int lower_bound(int k){
if(prefixsum(sz)<k) return -;
int l = , r = sz;
while(l <= r){
int mid = l + ((r-l)>>);
if(prefixsum(mid) < k) l = mid + ;
else r = mid - ;
}
return l;
} }solver; int ans[maxn]; int main(int argc,char *argv[]){
int Case;
scanf("%d",&Case);
while(Case--){
int n;
scanf("%d",&n);
solver.init(n);
for(int i = ; i <= n ; ++ i) scanf("%I64d",arr+i);
for(int i = ; i <= n ; ++ i) b[i] = arr[i] - arr[i-];
for(int i = ; i <= n ; ++ i) solver.updata(i , );
for(int i = n ; i >= ; -- i){
long long rank = i - b[i];
int t = solver.lower_bound(rank);
ans[i] = t;
solver.updata(t,-);
}
printf("%d",ans[]);
for(int i = ; i <= n ; ++ i) printf(" %d",ans[i]);
printf("\n");
}
return ;
}

代码

二分法

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e5+, M = , mod = 1e9+, inf = 0x3f3f3f3f;
typedef long long ll;
//不同为1,相同为0 int n;
struct BIT {
int tree[N] ; int lowbit(int x) {
return x&(-x);
}
void add(int x, int add, int n) {
for (; x <= n; x += lowbit(x)) {
tree[x] += add;
}
}
int sum(int x) {
int s = ;
for (; x > ; x -= lowbit(x)) {
s += tree[x];
}
return s;
}
void clears() {
memset(tree, , sizeof tree);
}
}Bit;
int cal(int x) {
int l = , r = n, ret = -;
while(l<=r) {
int mid = (l+r)>>;
int G = Bit.sum(n) - Bit.sum(mid-);
if(G>=x) l = mid+, ret = mid;
else r = mid-;
}
return ret;
}
int main() {
int T,b[N],a[N],ans[N];
scanf("%d",&T);
while(T--) {
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&a[i]),b[i] = a[i] - a[i-];
Bit.clears();
for(int i=;i<=n;i++) Bit.add(i,,n);
int pos = n - b[n];
ans[n] = pos;
Bit.add(pos,-,n);
for(int i = n-;i >= ;i--) {
pos = cal(b[i]+);
ans[i] = pos;
Bit.add(pos,-,n);
}
for(int i=;i<n;i++) {
printf("%d ",ans[i]);
}
printf("%d\n",ans[n]);
}
return ;
}

hdu5592/BestCoder Round #65 树状数组寻找第K大的更多相关文章

  1. HDU 5249 离线树状数组求第k大+离散化

    KPI Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  2. poj 2985 The k-th Largest Group 树状数组求第K大

    The k-th Largest Group Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 8353   Accepted ...

  3. 【转载】【树状数组区间第K大/小】

    原帖:http://www.cnblogs.com/zgmf_x20a/archive/2008/11/15/1334109.html 回顾树状数组的定义,注意到有如下两条性质: 一,c[ans]=s ...

  4. POJ2985 The k-th Largest Group[树状数组求第k大值+并查集||treap+并查集]

    The k-th Largest Group Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 8807   Accepted ...

  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. 树状数组求第K大(From CLJ)

    ; <<log2[n];p;p>>=) if(a[ret+p]<=kth) kth-=a[ret+=p]; return ret;

  7. hdu 4217 Data Structure? 树状数组求第K小

    Data Structure? Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  8. 树状数组求第k小的元素

    int find_kth(int k) { int ans = 0,cnt = 0; for (int i = 20;i >= 0;i--) //这里的20适当的取值,与MAX_VAL有关,一般 ...

  9. Mishka and Interesting sum Codeforces Round #365 (树状数组)

    树状数组,与Turing Tree类似. xr[i]表示从1到i的抑或,树状数组维护从1到i每个数只考虑一次的异或,结果为sum(r) ^ sum(l) ^ xr[r] ^ xr[l] 其中xr[r] ...

随机推荐

  1. Excel 查找某列中的数据在另一列是否存在并输出其他列的数据

    最近在操作Excel文件数据导入数据库时,经常需要检查Excel中哪些数据数据库中已经存在,哪些不存在,然后再将不存在数据库中的Excel数据导入:在此过程中,经常需要操作Excel中的数据,所以.也 ...

  2. 27. Remove Element[E]移除元素

    题目 Given an array nums and a value val, remove all instances of that value in-place and return the n ...

  3. [原创]Eclipse 安卓开发几个异常的处理办法

    一.代码没有问题,就是报错,重启一下就会好.可以先clean再build; 二.R.Java丢失 网上讲了若干方法,有用android toos的,有clean再build的,我的解决办法是勾选bui ...

  4. hdu2112 HDU Today 基础最短路

    这题的关键是把车站的名字转化为点的编号.我用的是map.声明一个map<string,int> st,然后按照字符串出现的次序给st赋值.例如:st[s1]=2;代表这字符串s1出现的次序 ...

  5. YARN环境搭建 之 二:CentOS7.0 JDK配置

    Hadoop是Java写的,他无法使用Linux预安装的OpenJDK,因此安装hadoop前需要先安装JDK(1.6以上)   原材料:在Oracle官网下载的32位JDK:     说明: 1.C ...

  6. 使用Storm实现实时大数据分析!

    随着数据体积的越来越大,实时处理成为了许多机构需要面对的首要挑战.Shruthi Kumar和Siddharth Patankar在Dr.Dobb's上结合了汽车超速监视,为我们演示了使用Storm进 ...

  7. pycharm一些快捷键

    1.鼠标方法在内建函数上,Ctrl+B,看内建函数的定义 2.pycharm单行和多行注释快捷键   单多行注释就一个组合键:选中+Ctrl+/ 3.Python代码块批量添加Tab缩进    按Ta ...

  8. HAOI2006 受欢迎的牛 缩点

    不难分析出我们就是要求是否有唯一一个出度为0的强连通分量. Code: #include<cstdio> #include<stack> #include<algorit ...

  9. 小学生都能学会的python(一)2018.9.3

    一,小学生第一天 1,认识和了解python python的创始⼈为吉多·范罗苏姆(Guido van Rossum). python是一门解释性语言  弱类型语言 优点:(1).Python的定位是 ...

  10. 【hdu 6396】Swordsman

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 开k个优先队列.每个队列都满足从小到大那种.. 首先将所有的怪物加入到第一个队列中. 然后对于v[i]>=pq[i].top( ...