hdu 5592 线段树
来源:互联网 发布:薛之谦人品知乎 编辑:程序博客网 时间:2024/06/01 08:45
问题描述
ZYBZYBZYB有一个排列PPP,但他只记得PPP中每个前缀区间的逆序对数,现在他要求你还原这个排列.(i,j)(i<j)(i,j)(i < j)(i,j)(i<j)被称为一对逆序对当且仅当Ai>AjA_i>A_jAi>Aj
输入描述
第一行一个整数TTT表示数据组数。接下来每组数据:第一行一个正整数NNN,描述排列的长度.第二行NNN个正整数AiA_iAi,描述前缀区间[1,i][1,i][1,i]的逆序对数.数据保证合法.1≤T≤51 \leq T \leq 51≤T≤5,1≤N≤500001 \leq N \leq 500001≤N≤50000
输出描述
TTT行每行NNN个整数表示答案的排列.
输入样例
130 1 2
输出样例
3 1 2
题解:设fi是第i个前缀的逆序对数,pi是第i个位置上的数,则fi−fi−1是iii前面比pi大的数的个数.我们考虑倒着做,当我们处理完i后面的数,第i个数就是剩下的数中第f_i-f_{i-1}+1大的数,用线段树和树状数组可以轻松地求出当前第k个是1的位置,复杂度O(NlogN)
#include<cstdio>#include<algorithm>#include<string>#include<iostream>using namespace std;#define lson rt<<1,l,m#define rson rt<<1|1,m+1,rconst int maxn=50009;int a[maxn<<2],ans[maxn<<2];int sum[maxn<<2];void pushup(int rt){ sum[rt]=sum[rt<<1]+sum[rt<<1|1];}void build(int rt,int l,int r){ if(l==r){ sum[rt]=1; return; } int m=(l+r)>>1; build(lson); build(rson); pushup(rt);}int querry(int rt,int l,int r,int v){ if(l==r){ sum[rt]=0; return l; } int res; int m=(l+r)>>1; if(sum[rt<<1|1]>=v)res=querry(rson,v); else res=querry(lson,v-sum[rt<<1|1]); pushup(rt); return res;}int main(){ int t; cin>>t; while(t--){ int n; scanf("%d",&n); a[0]=0; for(int i=1;i<=n;i++)scanf("%d",&a[i]); build(1,1,n); for(int i=n;i>=1;i--){ int f=a[i]-a[i-1]; ans[i]=querry(1,1,n,f+1); } for(int i=1;i<=n;i++) printf("%d%c",ans[i],(i==n)?'\n':' '); }}
0 0
- HDU 5592 (线段树)
- hdu 5592 线段树
- HDU 5592 线段树
- hdu 5592 线段树
- hdu 5592 线段树 + 二分
- HDU 5592 ZYB's Premutation 线段树
- hdu 5592 ZYB's Premutation (线段树)
- HDU 5592(ZYB's Premutation-线段树)
- hdu 5592 ZYB's Premutation 线段树
- hdu-5592 ZYB's Premutation(线段树)
- hdu 1754 线段树
- hdu 1754 线段树
- HDU 1698 线段树
- hdu 1754 线段树
- 【线段树】hdu 1754
- hdu-1166 线段树
- HDU-2688 线段树
- HDU 4027 线段树
- 关于如何管理文档中的参考文献
- day2:如何实现一个Virtual DOM算法 和 MVVM、MV*等模式的学习
- 常用图片格式及其特点
- unity3d利用Loading界面异步过渡游戏场景
- HDU 5593 树形DP
- hdu 5592 线段树
- HDU 5592 线段树
- 解析自动化测试的理解误区
- 学习Golang的步骤建议
- 模板大全
- BestCoder Round #65
- 中缀表达式,前缀表达式,后缀表达式
- JUnit的jar包和hamcrest的jar包关系
- python随机数整理