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 ;
}

最新文章

  1. 学习Maven之Properties Maven Plugin
  2. Ubuntu播放yuv文件
  3. 短信猫 TIdTCPServer TIdTCPClient
  4. update openssl on redhat/centos
  5. BZOJ1037: [ZJOI2008]生日聚会Party
  6. ubuntu install opengrok
  7. logback 设置按天,文件切割大小,总共日志文件大小。
  8. uva 11367 (Dijkstra+DP)
  9. 【温暖】文龙回AICODER给老马送锦旗了
  10. 【转】导致SQL执行慢的原因
  11. day22 Pythonpython random随机模块:略!!!本文os模块
  12. Copycat - AppendRequest
  13. Python3学习之路~6.2 实例演示面向对象编程的好处
  14. 动态规划之115 Distinct Subsequences
  15. git中工作区,缓存区,本地库,远程库的简要区别
  16. mac下查看jdk安装版本及安装目录
  17. Inter exchange Client Address Protocol (ICAP)- 互换客户端地址协议
  18. 微信小程序入门与实战
  19. 18B树、B++树和Trie树
  20. struts2学习(1)struts2 helloWorld

热门文章

  1. Redis位图法记录在线用户的状态
  2. js作业
  3. 利用a链接发送电子邮件
  4. MemCached总结二:数据管理指令
  5. WPF 解决拼接屏全屏的问题
  6. 三维重建:Kinect几何映射-SDK景深数据处理
  7. WebLogic安装使用及常见问题
  8. CDR教程-海报中的立体星星怎么画
  9. siblings() next() nextAll() nextUntil() prev() prevAll() prevUntil() 在 DOM 树中水平遍历
  10. hibernate简单集合映射和获取