hdu 5200(离线处理)
来源:互联网 发布:网络平台开发合同 编辑:程序博客网 时间:2024/04/19 17:17
Trees
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 numberedz , 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?
1)x+1=y or y+1=x;
2)there exists an uncutted tree which is numbered
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 integersN and Q separated by exactly one space, N indicates there are N trees, Q indicates there are Q queries.
In the followingN lines, there will appear h[1],h[2],h[3],…,h[N] which indicates the height of the trees.
In the followingQ 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)
For each case, first line contains two integers
In the following
In the following
Please process to the end of file.
[Technical Specification]
Output
For each q[i] , output the number of tree block after CodeFamer cut the trees whose height are not larger thanq[i] .
Sample Input
3 252362
Sample Output
02HintIn 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.解题思路:我一开始用的是在线算法,用并查集去处理,结果超时了#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<set>using namespace std;const int maxn = 50005;struct Node{int h,id;Node(){}Node(int _h,int _id){h = _h;id = _id;}bool operator < (const Node t) const{return h < t.h;}}tree[maxn];int n,q,height[maxn],fa[maxn];set<int> Set;int find(int x){if(fa[x] == x) return x;return fa[x] = find(fa[x]);}int main(){while(scanf("%d%d",&n,&q)!=EOF){for(int i = 1; i <= n; i++){scanf("%d",&height[i]);tree[i].h = height[i];tree[i].id = i;}sort(tree+1,tree+1+n);while(q--){int t;scanf("%d",&t);Set.clear();int pos = lower_bound(tree+1,tree+1+n,Node(t+1,0)) - tree;if(pos == n && tree[n].h != t+1){printf("0\n");continue;}int cnt = pos - 1;for(int i = 1; i <= pos; i++) fa[tree[i].id] = tree[i].id;for(int i = 1; i < pos; i++){int id = tree[i].id;if(Set.find(id-1) != Set.end()){int fx = find(id);int fy = find(id-1);if(fx != fy){fa[fy] = fx;cnt--;}}if(Set.find(id+1) != Set.end()){int fx = find(id);int fy = find(id+1);if(fx != fy){cnt--;fa[fy] = fx;}}Set.insert(id);}int ans = cnt + 1;if(height[1] <= t) ans--;if(height[n] <= t) ans--;printf("%d\n",ans);}}return 0;}查看了别人的思路,感觉自己对离线算法还是不太熟悉:对于每一个询问,若后一个询问高度大于前一个询问的高度,则后一个询问可以在前一个询问的基础上得到。就是说,前一个询问中已经砍掉了的那部分的树,在后一个询问中必然也是要砍掉的。为避免重复计算,可以用离线处理,将每一个询问,按照高度由低到高排序,然后依次处理。
首先对树按照由低到高排序,再对查询进行排序。然后,对于每一个询问,按高度依次删除树高度小于查询高度的树,每一次删除,查看删除的树的两边位置是否有树,若都没有,则砍掉之后会少一个块;若都有,则砍掉后会形成两个块,即增加1个块;若一边有,一边无,则块个数不变。注意对于边界的处理:编号为1的树和编号为n的树的左、右均标记为无树(即已砍倒)。
#include<iostream>#include<cstdio>#include<cmath>#include<map>#include<cstring>#include<algorithm>using namespace std;#define LL long long#define N 50005struct T{ int h,id;}t[N],p[N];int ans[N];int v[N];bool cmp(T a,T b) {return a.h<b.h;}int main(){ int i,j,n,q; while(~scanf("%d%d",&n,&q)) { for(i=0;i<n;i++) { v[i+1]=0; scanf("%d",&t[i].h); t[i].id=i+1; } v[0]=v[n+1]=1; sort(t,t+n,cmp); for(i=0;i<q;++i) { scanf("%d",&p[i].h); p[i].id=i; } sort(p,p+q,cmp); int s=1; for(i=0,j=0;i<q;++i) { while(j<n&&t[j].h<=p[i].h) { int tem=v[t[j].id+1]+v[t[j].id-1]; v[t[j].id]=1; if(tem==0) ++s; else if(tem==2) --s; j++; } ans[p[i].id]=s; } for(i=0;i<q;i++)printf("%d\n",ans[i]); } return 0;}
0 0
- hdu 5200(离线处理)
- hdu 5200 trees(离线处理)
- hdu 5200 离线处理+思维
- hdu 5200 Trees(离线处理,排序)
- hdu 5139 (离线处理)
- hdu 5139(离线处理)
- hdu 离线处理题目集锦
- hdu 4995 离线处理+模拟
- HDU 5139 Formula 离线处理
- HDU 5139 Formula(离线处理)
- hdu 4417 线段树离线处理
- hdu 4348 线段树离线处理
- HDU 3874 树状数组 + 离线处理
- HDU 3333 树状数组+离线处理
- HDU 3874 Necklace 树状数组 + 离线处理
- HDU 3874 Necklace(树状数组+离线处理)
- hdu 3333 树状数组+离线处理
- hdu 3874 树状数组+离线处理
- WIN10心得
- 了解ATM是什么
- 神秘的 IEEE
- 怎样做好软件测试经理
- Codeforces Round #361 (Div. 2) C. Mike and Chocolate Thieves (二分法)
- hdu 5200(离线处理)
- Not a PNG file...Error Execution failed for task app mergeDebugResource...问题解决
- 构建BI涉及的技术图
- paint Canvas画笔、画布
- json字符串转json
- 线程
- poj 3376 扩展kmp求回文加字典树
- 杂谈:再说手游审批政策
- yeoman的generator列表难以访问解决方案