UVa:1232 SKYLINE

来源:互联网 发布:董小飒电竞淘宝店 编辑:程序博客网 时间:2024/05/16 19:14

线段树维护区间最值和区间替换。

1。设setv,maxv,minv分别表示区间替换值和区间最大值和最小值。在找到目标的区间后,如果setv大于当前区间最大值,说明该区间都可以,ans+=L-R+1,同时更新该区间,注意这里maxv和minv都要改成setv。如果setv小于当前区间最小值,那就没有必要更新了,就中断update。其他情况就继续下传。

2。结点信息下传的时候,minv要取该段区间的setv和minv的较大值。

3。结点信息上传的时候,minv维护最小值,maxv维护最大值。

4。原来的线段树中的点表示的是线段,这里是点。所以右端点需要自减一。

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <cmath>#include <vector>#include <queue>#include <set>#include <map>#include <algorithm>#define ll  long long#define INF 2139062143#define inf -2139062144#define MOD 20071027#define MAXN  30#define LEN 111111<<2using namespace std;int ans;struct Line_Tree{private:    int setv[LEN],maxv[LEN],minv[LEN];    int sz,ql,qr,sv;    void PushUp(int o)    {        maxv[o]=max(maxv[o<<1],maxv[o<<1|1]);        minv[o]=min(minv[o<<1],minv[o<<1|1]);    }    void Pushdown(int o)    {        if(setv[o])        {            setv[o<<1]=setv[o];            setv[o<<1|1]=setv[o];            maxv[o<<1]=max(maxv[o<<1],setv[o<<1]);            maxv[o<<1|1]=max(maxv[o<<1|1],setv[o<<1|1]);            minv[o<<1]=max(minv[o<<1],setv[o<<1]);            minv[o<<1|1]=max(minv[o<<1|1],setv[o<<1|1]);            setv[o]=0;        }    }    void myupdate(int o,int L,int R)    {        if(ql<=L&&R<=qr)        {            if(sv>=maxv[o])            {                ans+=R-L+1;                setv[o]=sv;                maxv[o]=sv;                minv[o]=sv;                return ;            }            if(sv<=minv[o]||L==R) return ;        }        Pushdown(o);        int M=(L+R)>>1;        if(ql<=M) myupdate(o<<1,L,M);        if(M<qr) myupdate(o<<1|1,M+1,R);        PushUp(o);    }public:    void init(int n)    {        sz=n;        memset(setv,0,sizeof(setv));        memset(maxv,0,sizeof(maxv));        memset(minv,0,sizeof(minv));    }    void update(int a,int L,int R)    {        sv=a;        ql=L;        qr=R;        myupdate(1,1,sz);    }};Line_Tree tree;int main(){    int T;    scanf("%d",&T);    int n;    while(scanf("%d",&n)!=EOF&&n)    {        tree.init(100000);        ans=0;        int x,y,z;        for(int i=0; i<n; ++i)        {            scanf("%d%d%d",&x,&y,&z);            tree.update(z,x,y-1);        }        printf("%d\n",ans);    }    return 0;}


 

0 0