其他分享
首页 > 其他分享> > 锻炼 - Exercise - Indexed Tree

锻炼 - Exercise - Indexed Tree

作者:互联网

锻炼

时间限制:最多40个用例,1.5秒(C/C++),2秒(Java)/内存限制:256 MB(Stack 1 MB)

哲珉常去的健身房进了一种新的健身器材。该器材是以两柱子竖立的形态,每个柱子上有N+1个把手,各把手都以从下到上的方向贴着0到N的编号。

使用该器材进行锻炼时,需要用左手握住左侧柱子的0号把手,用右手握住右侧柱子的0号把手。然后,将双手向上移动到更高的把手来持续进行锻炼。

该器材附有一张表,表上以成对的形式写着多个左右把手的编号。锻炼者只能同时握住表上写着的一对把手编号。即,若表上有(3, 4),那么可以同时握住左侧3号把手和右侧4号把手。若表中没有(2, 6),那么不能同时握住左侧2号把手和右侧6号把手。

哲珉希望通过一次获得最大程度的锻炼,但锻炼量和他同时移动双手的次数成正比。换句话说,当双手移动的次数越多,能达到的锻炼量就越大。

 

 

比如说,假设N=10,并且表中的成对编号为 (2, 3)、(1, 1)、(5, 5)、(7, 4)、(6, 8)、(10, 1)。在这种情况下,双手移动次数最多的一种方法是以 (0, 0)、(1, 1)、(2, 3)、(5, 5)、(6, 8) 的顺序握住把手。这时,双手移动的次数为四次,然而锻炼量达到了最大。

请写一个程序,通过接收健身器材的表来计算双手能移动的最大次数。

 

[限制条件]

1.把手的最大编号N是介于1到1,000,000,000之间。

2.给出的编号成对个数M是介于1到300,000之间。

 

[输入]

第一行给出测试用例数量T。接着给出T个测试用例。各个用例的第一行给出把手编号的最大值N和成对个数M。接下来通过M行,每行给出一对左右把手的编号。

 

[输出]

各测试用例的答案按照顺序标准输出。每个测试用例输出“#x”(其中x表示测试用例编号,从1开始),加一个空格(不带引号),输出题目中要求的双手能移动的最大次数。

 

[输入输出 示例]

(输入)

2

10 6

2 3

1 1

5 5

7 4

6 8

10 1

14 8

8 10

1 2

3 4

2 3

14 13

4 4

9 13

7 9

 

(输出)

#1 4

#2 6

 

思路:数据有两列,如果对一列排序,那么只需要求另一列的LIS即可
因此,可使用Indexed Tree或者DP+二分查找的方式
使用Indexed Tree时,因为N的范围是10亿,如果直接使用N开数组,会超过可声明的范围,因此需要散列化

 

package tree;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.StringTokenizer;
import java.util.TreeSet;

/**
 * 思路:数据有两列,如果对一列排序,那么只需要求另一列的LIS即可
 * 因此,可使用Indexed Tree或者DP+二分查找的方式
 * 使用Indexed Tree时,因为N的范围是10亿,如果直接使用N开数组,会超过可声明的范围,因此需要散列化
 * @author XA-GDD
 *
 */
public class Exercise_0628 {

	static int T,N,M;
	static int _Max_M = 300000;
	static int [][] srcArr = new int[_Max_M+1][2];
	static int [] idxTree = new int[_Max_M*2];
	static int offset;
	static TreeSet<Integer> ts = new TreeSet<Integer>();
	static HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
	public static void main(String[] args) throws IOException {
		System.setIn(new FileInputStream("D:\\workspace\\sw_pro\\test_case\\sample_input_0628.txt"));
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	    StringTokenizer st = new StringTokenizer(br.readLine());
		T = Integer.parseInt(st.nextToken());
	    for(int testCase = 1; testCase<=T;testCase++) {
	    	init();
	    	st = new StringTokenizer(br.readLine());
	    	N = Integer.parseInt(st.nextToken());
	    	M = Integer.parseInt(st.nextToken());
	    	for(int i=0;i<M;i++) {
	    		st = new StringTokenizer(br.readLine());
	    		srcArr[i][0]=Integer.parseInt(st.nextToken());
	    		srcArr[i][1]=Integer.parseInt(st.nextToken());
	    		ts.add(srcArr[i][1]);
	    	}
	    	
	    	//对左侧的数据排序,左侧相同时,右侧逆序
	    	Arrays.sort(srcArr,0,M,new Comparator<int[]>() {
				@Override
				public int compare(int[] o1, int[] o2) {
					if(o1[0]==o2[0]) {
						return o2[1]-o1[1];
					}
					return o1[0]-o2[0];
				}
			});
	    	
	    	//散列化
	    	int index=0;
	    	for (int val : ts) {
				map.put(val, index++);
			}
	    	
	    	//indexed tree初始化
	    	int k=0;
	    	while((1<<k)<index) {
	    		k++;
	    	}
	    	offset=1<<k;
	    	
	    	for(int i=0;i<M;i++) {
	    		int val = query(offset,offset+map.get(srcArr[i][1])-1); //0~当前-1处LIS的最大值
	    		update(offset+map.get(srcArr[i][1]),val+1); //当前处的LIS长度=当前-1处的LIS+1
	    	}
	    	System.out.println("#"+testCase+" "+idxTree[1]);
	    }
	}
	static void update(int index,int val) {
		idxTree[index]=val;
		index = index>>1;
	    while(index>0) {
	    	idxTree[index] = Math.max(idxTree[index*2], idxTree[index*2+1]);
	    	index = index>>1;
	    }
	}
	
	static int query(int start, int end) {
		int res =0;
		while(start<=end) {
			if(start%2==1) {
				res = Math.max(res, idxTree[start]);
			}
			if(end%2==0) {
				res = Math.max(res, idxTree[end]);
			}
			start=(start+1)>>1;
			end=(end-1)>>1;
		}
		return res;
	}

	static void init() {
		for(int i=0;i<srcArr.length;i++) {
			Arrays.fill(srcArr[i], 0);
		}
		Arrays.fill(idxTree, 0);
		ts.clear();
		map.clear();
	}
}

  

 

标签:java,int,Tree,new,static,把手,Indexed,import,Exercise
来源: https://www.cnblogs.com/smile_to_warm/p/15072159.html