hdu5592/BestCoder Round #65 树状数组寻找第K大
ZYB's Premutation
ZYBZYB有一个排列PP,但他只记得PP中每个前缀区间的逆序对数,现在他要求你还原这个排列. (i,j)(i < j)(i,j)(i<j)被称为一对逆序对当且仅当A_i>A_jAi>Aj
第一行一个整数TT表示数据组数。 接下来每组数据: 第一行一个正整数NN,描述排列的长度. 第二行NN个正整数A_iAi,描述前缀区间[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_ifi是第ii个前缀的逆序对数,p_ipi是第ii个位置上的数,则f_i-f_{i-1}fi−fi−1是ii前面比p_ipi大的数的个数.我们考虑倒着做,当我们处理完ii后面的数,第ii个数就是剩下的数中第f_i-f_{i-1}+1fi−fi−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大的更多相关文章
- HDU 5249 离线树状数组求第k大+离散化
KPI Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
- poj 2985 The k-th Largest Group 树状数组求第K大
The k-th Largest Group Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 8353 Accepted ...
- 【转载】【树状数组区间第K大/小】
原帖:http://www.cnblogs.com/zgmf_x20a/archive/2008/11/15/1334109.html 回顾树状数组的定义,注意到有如下两条性质: 一,c[ans]=s ...
- POJ2985 The k-th Largest Group[树状数组求第k大值+并查集||treap+并查集]
The k-th Largest Group Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 8807 Accepted ...
- Permutation UVA - 11525(值域树状数组,树状数组区间第k大(离线),log方,log)(值域线段树第k大)
Permutation UVA - 11525 看康托展开 题目给出的式子(n=s[1]*(k-1)!+s[2]*(k-2)!+...+s[k]*0!)非常像逆康托展开(将n个数的所有排列按字典序排序 ...
- 树状数组求第K大(From CLJ)
; <<log2[n];p;p>>=) if(a[ret+p]<=kth) kth-=a[ret+=p]; return ret;
- hdu 4217 Data Structure? 树状数组求第K小
Data Structure? Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- 树状数组求第k小的元素
int find_kth(int k) { int ans = 0,cnt = 0; for (int i = 20;i >= 0;i--) //这里的20适当的取值,与MAX_VAL有关,一般 ...
- 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] ...
随机推荐
- 2018亚洲区预选赛北京赛站网络赛 D.80 Days 尺取
题面 题意:你带着K元要去n个城市,这n个城市是环形的,你可以选择任意一个起点,然后顺时针走,对于每个城市,到达时可以获得a元,但是从这里离开又需要花费b元,问你能否找到一个起点(输出花钱最少的那个) ...
- 谈谈JavaScript深浅拷贝
浅拷贝 function shallowCopy(source){ var newObj = {}; for(var attr in source){ newObj[attr] = source[at ...
- GObject调用父类函数
最近在分析Gstreamer的代码时,发现GstPipeline中有如下代码: result = GST_ELEMENT_CLASS (parent_class)->change_state ( ...
- caffe 参数介绍 solver.prototxt
转载自 http://blog.csdn.net/cyh_24/article/details/51537709 solver.prototxt net: "models/bvlc_alex ...
- B - Expression
Problem description Petya studies in a school and he adores Maths. His class has been studying arith ...
- java异常处理和自定义异常利用try和catch让程序继续下去(回来自己再写个例子试运行下)
注意:想在catch的参数里使用自定义的异常,则必须先将这个异常抛出才行.(throws是具有抛出异常的能力,并未抛出,throw new MyException是抛出异常,catch是捕获异常,只有 ...
- Hadoop MapReduce编程 API入门系列之MapReduce多种输入格式(十七)
不多说,直接上代码. 代码 package zhouls.bigdata.myMapReduce.ScoreCount; import java.io.DataInput; import java.i ...
- 第7章 性能和可靠性模式 Load-Balanced Cluster(负载平衡群集)
上下文 您已经决定在设计或修改基础结构层时使用群集,以便在能够适应不断变化的要求的同时保持良好的性能. 问题 在保持可接受的性能级别的同时,如何设计一个可适应负载变化的.可伸缩的基础结构层? 影响因素 ...
- 修改数组数据头和尾push()、pop()和unshift()、shift()
1.push().pop()和unshift().shift() 这两组同为对数组的操作,并且会改变数组的本身的长度及内容. 不同的是 push().pop() 是从数组的尾部进行增减,unshift ...
- Css float 盒子模型 position
属性: float 浮动 浮动的内容用div包起来,给div设置宽高 clear 清除浮动. box-sizing 标准模式下的盒模型 content-box:(默认属性) padding和borde ...