hdu 5200 Trees [ 排序 离线 2指针 ]

传送门

Trees

Accepts: 156

Submissions: 533

Time Limit: 2000/1000 MS (Java/Others)

Memory Limit: 65536/65536 K (Java/Others)

Problem Description

Today CodeFamer is going to cut trees.There are N trees standing in a line. They are numbered from 1 to N. The tree numbered i has height hi. We say that two uncutted trees whose numbers are x and y are in the same block if and only if they are fitting in one of blow rules:

1)x+1=y or y+1=x;

2)there exists an uncutted tree which is numbered z, and x is in the same block with z, while y is also in the same block with z.

Now CodeFamer want to cut some trees whose height is not larger than some value, after those trees are cut, how many tree blocks are there?

Input

Multi test cases (about 15).

For each case, first line contains two integers N and Q separated by exactly one space, N indicates there are N trees, Q indicates there are Q queries.

In the following N lines, there will appear h[1],h[2],h[3],…,h[N] which indicates the height of the trees.

In the following Q lines, there will appear q[1],q[2],q[3],…,q[Q] which indicates CodeFamer’s queries.

Please process to the end of file.

[Technical Specification]

1≤N,Q≤50000

0≤h[i]≤1000000000(109)

0≤q[i]≤1000000000(109)

Output

For each q[i], output the number of tree block after CodeFamer cut the trees whose height are not larger than q[i].

Sample Input

3 2
5
2
3
6
2

Sample Output

0
2

Hint

In this test case, there are 3 trees whose heights are 5 2 3. For the query 6, if CodeFamer cuts the tree whose height is not large than 6, the height form of left trees are -1 -1 -1(-1 means this tree was cut). Thus there is 0 block. For the query 2, if CodeFamer cuts the tree whose height is not large than 2, the height form of left trees are 5 -1 3(-1 means this tree was cut). Thus there are 2 blocks.

题解:

窝题目看错了,,悲催啊。。题解以代码均来自小微哥。

对树的高度和查询的高度都分别排序。

然后,两个指针操作,O(n+m)复杂度。

13341721 2015-04-04 21:14:13 Accepted 5200 702MS 4588K 1496 B C++ czy

代码来自小微哥:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 #define M 500005
 7
 8 struct point{
 9     int i, v;
10 }p[M];
11 struct node
12 {
13     int v;
14     int cur;
15 }s[M];
16 int has[M],  res[M];
17
18 bool cmp (point a, point b)
19 {
20     return a.v > b.v;
21 }
22 int S()
23 {
24     int ret=0,ok=0;
25     char c;
26     while((c=getchar()))
27     {
28         if(c>=‘0‘&&c<=‘9‘)
29         ret=(ret<<3)+ret+ret+c-‘0‘,ok=1;
30         else if(ok)
31         return ret;
32     }
33     return ret;
34 }
35 bool cmp2(node a,node b)
36 {
37     return a.v<b.v;
38 }
39 int main()
40 {
41     int  n, d, i, j, ans;
42     while (~scanf("%d%d",&n,&d))
43     {
44         for (i = 0; i < n; i++)
45         {
46             p[i].v=S();
47             p[i].i = i+1;
48         }
49         sort(p, p+n, cmp);
50         for (j = 0; j < d; j++)
51         {
52             s[j].v=S();
53             s[j].cur=j;
54         }
55         sort(s,s+d,cmp2);
56         memset(has, 0, sizeof(has));
57         ans = 0;
58         for (i = 0, j = d - 1; j >= 0; j--)
59         {
60             for ( ; i < n; i++)
61             {
62                 if (p[i].v <= s[j].v)
63                     break;
64                 int id = p[i].i;
65                 has[id] = 1;
66                 if (!has[id-1] && !has[id+1]) ++ans;
67                 else if (has[id-1] && has[id+1]) --ans;
68             }
69             res[s[j].cur] = ans;
70         }
71         for (i = 0; i < d; i++)
72         {
73             printf ("%d\n", res[i]);
74         }
75     }
76     return 0;
77 }
时间: 2024-12-23 07:44:52

hdu 5200 Trees [ 排序 离线 2指针 ]的相关文章

Hdu 5200 Trees (离线线段树)

题目大意: 校门外栽满了不同高度的树,每一次询问是 如果砍掉所有高度不超过q的树,那么还有多少个连续的块. 思路分析: 记录左连续和   右连续和  用来维护区间的连续块的数量. 即 seg[num] = seg[num<<1]+seg[num<<1|1] ; 如果中间部分连起来  那么减一即可. #include <cstdio> #include <iostream> #include <cstring> #include <algor

HDU - 5200 - Trees (upper_bound)

Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 205    Accepted Submission(s): 68 Problem Description Today CodeFamer is going to cut trees.There are N trees standing in a line. They are

HDU 1862 EXCEL排序 (排序水题)

Problem Description Excel可以对一组纪录按任意指定列排序.现请你编写程序实现类似功能. Input 测试输入包含若干测试用例.每个测试用例的第1行包含两个整数 N (<=100000) 和 C,其中 N 是纪录的条数,C 是指定排序的列号.以下有 N 行,每行包含一条学生纪录.每条学生纪录由学号(6位数字,同组测试中没有重复的学号).姓名(不超过8位且不包含空格的字符串).成绩(闭区间[0, 100]内的整数)组成,每个项目间用1个空格隔开.当读到 N=0 时,全部输入结

hdu 2020 绝对值排序

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2020 题目大意:按照绝对值大小从大到小排序,注意输出两个数之间要用空格隔开,在这里引入一个冒泡排序,两个循环即可! 1 #include <stdio.h> 2 #include <math.h> 3 int main () 4 { 5 int n,a[100],i,j,t; 6 while (scanf("%d",&n),n) 7 { 8 for (i=0

HDU 3333 Turing Tree (离线询问+线段树)

题目地址:HDU 3333 将询问离线保存下来,然后将数组的点离散化,记录每个值上一次出现的位置.然后枚举数组的数,若当前枚举的数前面出现过,那么就删掉前面出现过的那个位置上的数,更新当前这个位置上的数,然后那些所有询问的右端点为当前位置的就可以通过查询来得到结果了. 更新与查询用线段树来优化. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #

HDU 4857 拓扑排序 优先队列

n个数,已经有大小关系,现给m个约束,规定a在b之前,剩下的数要尽可能往前移.输出序列 大小关系显然使用拓扑结构,关键在于n个数本身就有大小关系,那么考虑反向建图,优先选择值最大的入度为零的点,这样得到的序列就是从大到小的,最后倒序输出就行了. 写这题的时候头好痛阿肚子好痛阿,再也不想熬夜了,一点效率都没有. /** @Date : 2017-09-29 19:29:12 * @FileName: HDU 4857 拓扑排序 + 优先队列.cpp * @Platform: Windows * @

HDU 5200 漂亮得像个女人的解法

线段树,TLE,各种.唉....我真是笨死了.... 我用的线段树是记录左右区间最长连续棵数的...反正TLE #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N=50050; struct Q{ int val,index; }Que[N]; int SegT[N*4],L[N*4],R[

HDU 5638 拓扑排序+优先队列

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5638 题意: 给你一个DAG图,删除k条边,使得能个得到字典序尽可能小的拓扑排序 题解: 把拓扑排序的算法稍微改一下,如果某个顶点的入度小于k也把它加到优先队列里面去. k减小后队列里面会有些点不满足<=k,直接踢出来就好了. 代码: #include<iostream> #include<cstring> #include<cstdio> #include<

HDU 4417 Super Mario(离线线段树or树状数组)

Problem Description Mario is world-famous plumber. His "burly" figure and amazing jumping ability reminded in our memory. Now the poor princess is in trouble again and Mario needs to save his lover. We regard the road to the boss's castle as a l