CodeforcesBeta Round #35 (Div. 2) E. Parade(线段树区间更新)
来源:互联网 发布:淘宝店铺上货教程 编辑:程序博客网 时间:2024/05/29 23:22
题意就是给你n个建筑,左坐标右坐标和高度,然后输出轮廓的节点。
思路在于离散化点后,要把线段树的根节点看作是线段,这样就是一个很简单的区间最大值覆盖,加个标记延迟更新就可以了~然后在加完后,还要进行一个DFS把所有标记推到底就OK了。输出也很容易,当跟前一个高度不一样就说明转弯了,输出2个点。为了方便输出,在加完后再在最后加一个高度为0的线段。
AC代码:
//#pragma comment(linker, "/STACK:102400000,102400000")#include<cstdio>#include<ctype.h>#include<algorithm>#include<iostream>#include<cstring>#include<vector>#include<cstdlib>#include<stack>#include<cmath>#include<queue>#include<set>#include<map>#include<ctime>#include<string.h>#include<string>#include<sstream>#include<bitset>using namespace std;#define ll long long#define eps 1e-4#define NMAX 200005#define MOD 1000000009#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1#define PI acos(-1)template<class T>inline void scan_d(T &ret){ char c; int flag = 0; ret=0; while(((c=getchar())<'0'||c>'9')&&c!='-'); if(c == '-') { flag = 1; c = getchar(); } while(c>='0'&&c<='9') ret=ret*10+(c-'0'),c=getchar(); if(flag) ret = -ret;}const int maxn = 100000+10;int T[maxn<<3];map<int, int>m;int a[maxn][3],b[maxn*2],ans[maxn*2];void build(int l, int r, int rt){ T[rt] = 0; if(l == r) return; int mid = (l+r)>>1; build(lson); build(rson);}void pushdown(int rt){ if(T[rt]) { T[rt<<1] = max(T[rt],T[rt<<1]); T[rt<<1|1] = max(T[rt],T[rt<<1|1]); T[rt] = 0; }}void updata(int L, int R, int h, int l, int r, int rt){ if(L <= l && R >= r) { T[rt] = max(T[rt],h); return; } pushdown(rt); int mid = (l+r)>>1; if(L <= mid) updata(L, R, h, lson); if(R > mid) updata(L, R, h, rson);}void dfs(int l, int r, int rt){ if(l == r) { ans[l] = T[rt]; return; } pushdown(rt); int mid = (l+r)>>1; dfs(lson); dfs(rson);}int main(){#ifdef GLQ freopen("input.txt","r",stdin);// freopen("o4.txt","w",stdout);#endif // GLQ freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); int n; while(~scanf("%d",&n)) { for(int i = 0; i < n; i++) { scanf("%d%d%d",&a[i][0],&a[i][1],&a[i][2]); b[2*i] = a[i][1]; b[2*i+1] = a[i][2]; } sort(b,b+2*n); int nct = unique(b,b+2*n) - b; for(int i = 0; i < nct; i++) m[b[i]] = i+1; build(1,nct,1); for(int i = 0; i < n; i++) {// cout<<"ha:"<<m[a[i][1]]<<" "<<m[a[i][2]]-1<<endl; updata(m[a[i][1]],m[a[i][2]]-1,a[i][0],1,nct,1); } updata(nct-1,nct-1,0,1,nct,1); dfs(1,nct,1); int kk = 2; for(int i = 2; i <= nct; i++) if(ans[i] != ans[i-1]) kk += 2; printf("%d\n",kk); printf("%d %d\n",b[0],0); printf("%d %d\n",b[0],ans[1]); for(int i = 2; i <= nct; i++) if(ans[i] != ans[i-1]) { printf("%d %d\n",b[i-1],ans[i-1]); printf("%d %d\n",b[i-1],ans[i]); } } return 0;}
0 0
- CodeforcesBeta Round #35 (Div. 2) E. Parade(线段树区间更新)
- CodeForces 35E Parade(线段树区间更新+离散化)
- Codeforces Beta Round #35 (Div. 2) E. Parade(成段更新)
- Parade - CodeForces #35 (Div. 2) E 线段树
- Codeforces Round #442 (Div. 2)-E-Danil and a Part-time Job(DFS序+线段树区间更新)
- .CodeforcesBeta Round #19 D. Points 线段树 单点更新
- Codeforces Round #FF (Div. 2)E(线段树成段更新)
- Codeforces Round #263 (Div. 2)E(线段树点更新)
- Codeforces Beta Round #35 (Div. 2) E (区间倍增处理区间问题,成段更新,必掌握)
- CodeforcesBeta Round #19 D. Points(线段树)
- [CodeforcesBeta Round #19 D. Points] (线段树)
- CodeforcesBeta Round #19 D. Points (线段树)
- Codeforces Round #149 (Div. 2) E. XOR on Segment(21棵线段树处理每一位+区间异或)
- 【线段树延迟更新】Codeforces Round #104 (Div. 1) E
- Codeforces 35E Parade(扫描线 线段树||STL)
- 【CodeForces】35E Parade 线段树
- CodeforcesBeta Round #19 D. Points 离线线段树 单点更新 离散化
- Codeforces Round #442 (Div. 2) E. Danil and a Part-time Job (dfs序树型转线性 线段树区间修改区间查询)
- 收集的WMIC命令
- ermission denied: user=root, access=WRITE, inode="hadoop":hadoop:supergroup:rwxr-xr-x
- 《人月神话》读后感
- 常用的.net开源项目
- HDU 1166 敌兵布阵
- CodeforcesBeta Round #35 (Div. 2) E. Parade(线段树区间更新)
- Remedy Developer Stuido Drop-Down List 和 Character的default value的区别
- 堆排序
- PHP定时 & cpanel守护作业
- HDU 5091 Beam Cannon(线段树)
- .Net Framework下的多线程安全集合
- Java 接口(interface)的用途和好处
- LeetCode 循环链表II
- ext的getValue()和getRawValue()的区别