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