ZYB's Premutation(挺简单的数据结构题目)

本文探讨了一个关于序列重构的问题,通过分析给定的前缀逆序对数量,求解原始序列。采用二分搜索与区间树状数组进行优化,有效解决了复杂度较高的输入数据处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ZYB's Premutation

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 554    Accepted Submission(s): 271


Problem Description
ZYB has a premutation P ,but he only remeber the reverse log of each prefix of the premutation,now he ask you to
restore the premutation.

Pair (i,j)(i<j) is considered as a reverse log if Ai>Aj is matched.
 

Input
In the first line there is the number of testcases T.

For each teatcase:

In the first line there is one number N .

In the next line there are N numbers Ai ,describe the number of the reverse logs of each prefix,

The input is correct.

1T5 , 1N50000
 

Output
For each testcase,print the ans.
 

Sample Input
  
1 3 0 1 2
 

Sample Output
  
3 1 2
 

Source

题意: HDU上有中文题面,题意我就不呵呵了
题解: 很容易想到,从数组后面往前推,因为最后一个数我们可以确定其位置,接下来就是代码优化问题。直接暴力跑的话是会超时的。这题我用的是二分位置,加区间树状数组验证答案。

AC代码:
import java.util.*;
import java.io.*;

public class main{
	
	static Scanner cin = new Scanner(System.in);
	static PrintWriter out = new PrintWriter(System.out);
	static int[] a = new int[50005];
	static int[] c = new int[50005];
	static int n;
	
	public static void main(String[] args) throws IOException{
		int T = cin.nextInt();
		while(T-- > 0) {
			int pre = -1,now;
			n = cin.nextInt();
			for(int i = 1; i <= n; i++) {
				a[i] = cin.nextInt();
				if(pre == -1) pre = a[i];
				else {
					now = a[i] - pre; 
					pre = a[i];
					a[i] = now; 
				}
			}
			Arrays.fill(c, 0);
			for(int i = n; i >= 1; i--) {
				int l = 1,r = n,ans = 0;
				while(l <= r) {
					int mid = l + r >> 1;
					int tp = n - mid - que(mid + 1, n);
					if(tp > a[i] || tp == a[i] && que(mid, mid) == 0) {
						ans = mid;
						l = mid + 1;
					} else {
						r = mid - 1;
					}
				}
				a[i] = ans;
				add(ans);
			}
			boolean ok = false;
			for(int i = 1; i <= n; i++) {
				if(ok) System.out.print(' ');
				else ok = true;
				System.out.print(a[i]);
			}
			System.out.println();
		}
	}
	public static void add(int x) {
		while(x <= n) {
			c[x]++;
			x += x & -x;
		}
	}
	public static int que(int l,int r) {
		int s = 0;
		if(l > r) return s;
		while(r > 0) {
			s += c[r];
			r -= r & -r;
		}
		l--;
		while(l > 0) {
			s -= c[l];
			l -= l & -l;
		}
		return s;
	}
}


 
### 计算机数据结构的分层概念 计算机中的数据结构可以被看作是一种逻辑上的抽象表示方法,用于组织和存储数据以便于高效访问和修改。虽然严格意义上,“分层”这一术语更多应用于计算机网络领域[^2],但在讨论数据结构时也可以引入类似的层次化思维来理解其复杂性和相互依赖的关系。 #### 1. 基础层:简单数据类型 最底层的数据结构简单的数据类型构成,例如整数、浮点数、字符等基本单位。这些是最原始的数据单元,在程序设计中通常作为构建更复杂数据结构的基础[^3]。 #### 2. 中间层:线性数据结构 在此之上的是各种线性数据结构,比如数组、链表、栈和队列。它们的特点在于元素之间存在一对一或者顺序排列的关系。 - **数组** 是一种连续内存分配方式下的固定大小集合体; - **链表** 则通过指针连接节点形成动态可变长度序列[^1]。 ```c++ // 链表定义示例 struct Node { int data; struct Node* next; // 指向下一个结点的指针 }; ``` #### 3. 上层:非线性数据结构 更高一层是非线性的高级数据结构,包括树形结构(如二叉树)、图以及哈希表等形式。这类结构能够表达更加复杂的关联模式: - **树** 提供了一种分级管理机制; - **图** 可用来描述任意对象间的多对多联系; - 而 **哈希表** 实现快速查找操作。 ```python class TreeNode: def __init__(self, value=0, left=None, right=None): self.value = value self.left = left self.right = right ``` #### 4. 应用层:复合型数据结构 最终到达应用层面,则会遇到许多基于上述几种基础形式组合而成的新颖解决方案——即所谓的“复合型”或定制化的特殊用途数据结构。这一步骤往往取决于特定应用场景的需求分析结果而定。 --- ### 总结 综上所述,尽管传统意义上的“分层”主要适用于通信协议等领域,但对于理解和掌握各类不同的数据结构及其内部运作原理而言,采用逐级递增的方式来思考仍然具有重要意义。每一层级都建立在其下一级别的基础上,并且随着高度增加逐渐变得更加灵活多样但也更为复杂难懂。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值