zoukankan      html  css  js  c++  java
  • 【笔记】【线段树】矩形面积交 矩形周长

    【1】底边固定的矩形面积交

    这是我第一次不知道知识点的时候,瞎用区间最大最小值,做的面积交

    还挺快

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #define lnt long long 
    using namespace std;
    int n;
    const int N=1e9+3,M=40003;
    struct node
    {
        int x,id,pos;
        bool operator < (const node & o ) const
        { return x<o.x; }
    }ask[M<<1];
    int tot,ll[M][2],h[M]; 
    int td[M][2],d[M<<1];
    
    int root,cnt;
    int ls[M<<2],rs[M<<2],len[M<<2];
    int laz[M<<2],mn[M<<2],mx[M<<2];
    void updata(int rt)
    {
        mn[rt]=min(mn[ls[rt]],mn[rs[rt]]),
        mx[rt]=max(mx[ls[rt]],mx[rs[rt]]);
    }
    void build(int &rt,int l,int r)
    {
        rt=++cnt;
        if(l==r) 
        {
            len[rt]=d[l+1]-d[l];
            return ;
        }
        
        int mid=(l+r)>>1;
        build(ls[rt],l,mid);
        build(rs[rt],mid+1,r);
        len[rt]=len[ls[rt]]+len[rs[rt]];
        updata(rt);
    }
    void push_down(int rt)
    {
        mn[ls[rt]]=mx[ls[rt]]=laz[ls[rt]]=laz[rt];
        mn[rs[rt]]=mx[rs[rt]]=laz[rs[rt]]=laz[rt];
        laz[rt]=0;
    }
    bool change(int rt,int l,int r,int ql,int qr,int h)
    {
        if(mn[rt]>=h ) return false;
        if(ql<=l && r<=qr && mx[rt]<=h )
        {
            mx[rt]=laz[rt]=mn[rt]=h;
            return true;
        }
        if(l==r) return false;
        
        if(laz[rt] ) push_down(rt);
        int mid=(l+r)>>1; bool cg=false;
        if(ql<=mid) cg|=change(ls[rt],l,mid,ql,qr,h);
        if(qr> mid) cg|=change(rs[rt],mid+1,r,ql,qr,h);
        if(cg ) updata(rt);
    }
    lnt query(int rt,int l,int r)
    {
        if(mx[rt]==mn[rt]) 
            return 1LL*len[rt]*mx[rt];
        
        if(laz[rt] ) push_down(rt);
        int mid=(l+r)>>1;
        lnt ans=query(ls[rt],l,mid) ;
        return ans+query(rs[rt],mid+1,r);
    }
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {   
            scanf("%d%d%d",&ll[i][0],&ll[i][1],&h[i]);
            if(ll[i][0] <= ll[i][1])
            {
                ask[++tot].x =ll[i][0],ask[tot].id =i,ask[tot].pos =0;
                ask[++tot].x =ll[i][1],ask[tot].id =i,ask[tot].pos =1;
            }
        }
        sort(ask+1,ask+tot+1);
        int nn=0;
        for(int i=1;i<=tot;i++)
            if(ask[i].x ==ask[i-1].x )  
                ll[ask[i].id ][ask[i].pos ]=ll[ask[i-1].id ][ask[i-1].pos ];
            else 
            {
                d[++nn]=ll[ask[i].id ][ask[i].pos ] ; 
                ll[ask[i].id ][ask[i].pos ]=nn ;
            }
        d[nn+1]=d[nn];
        
        build(root,1,nn);
        for(int i=1;i<=n;i++)
            if(ll[i][0] <= ll[i][1] )
                change(root,1,nn,ll[i][0],ll[i][1]-1,h[i]);
        printf("%lld
    ",query(root,1,nn));
        return 0;
    }

    【2】矩形周长和

    (1)未离散版

    USACO picture

    我调了一下午......所以就没有离散版了

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    using namespace std;
    int n;
    const int N=5003,M=20003;
    
    int cnt;
    struct node
    {
        int h,l,r,w;
        bool operator < (const node & o ) const
        { return h!=o.h ?h<o.h :w>o.w ; }
    }d[N<<2];
    
    int root,tot,ls[M<<1],rs[M<<1];
    int tm[M<<1],len[M<<1],num[M<<1];//这里的tm其实就是laz标记,只不过有很多次 
    bool fl[M<<1],fr[M<<1];
    void build(int &rt,int l,int r)
    {
        rt=++tot;
        if(l==r ) return ;
        int mid=(l+r)>>1;
        build(ls[rt],l,mid),build(rs[rt],mid+1,r);
    }
    
    void updata(int rt)
    {
        len[rt]=len[ls[rt]]+len[rs[rt]];
        num[rt]=num[ls[rt]]+num[rs[rt]]- (fr[ls[rt]]&fl[rs[rt]]);
        fl[rt]=fl[ls[rt]],fr[rt]=fr[rs[rt]];
    }
    int ql,qr,v;
    void change(int rt,int l,int r)
    {
        if(ql<=l && r<=qr )
        {
            tm[rt]+=v;
            if(tm[rt] )
                len[rt]=r-l+1,num[rt]=1,fl[rt]=fr[rt]=true;
            else
                if(l==r ) len[rt]=num[rt]=0,fl[rt]=fr[rt]=false;
                else updata(rt);//区间覆盖问题 的删除操作,比较复杂 
            return ;
        }
        
        //因为懒惰标记 对操作没有影响(覆盖于加法不同)
        //所以修改后面的,再updata就行
        int mid=(l+r)>>1;
        if(ql<=mid ) change(ls[rt],l,mid);
        if(qr> mid ) change(rs[rt],mid+1,r);
        if(!tm[rt] ) updata(rt);
    }
    
    int main()
    {
        scanf("%d",&n);
        int x[2],y[2],mny=1<<30,mxy=1<<31;
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d%d%d",&x[0],&y[0],&x[1],&y[1]); y[1]--;
            mny=min(mny,y[0]),mxy=max(mxy,y[1]);
            d[++cnt].h =x[0],d[cnt].l =y[0],d[cnt].r =y[1],d[cnt].w = 1;
            d[++cnt].h =x[1],d[cnt].l =y[0],d[cnt].r =y[1],d[cnt].w =-1;
        }
        sort(d+1,d+cnt+1);
        d[cnt+1].h =d[cnt].h ;
        
        build(root,mny,mxy);
        int ans=0,pre=0;
        for(int i=1;i<=cnt;i++)
        {
            ql=d[i].l ,qr=d[i].r ,v=d[i].w ;
            change(root,mny,mxy );
    //        printf("%d %d %d
    ",ql,qr,v);
            ans+=abs(len[1]-pre); 
            ans+=(d[i+1].h -d[i].h )*num[1]*2;
    //        printf(" %d %d
    ",abs(len[1]-pre),(d[i+1].h -d[i].h )*num[1]*2);
            pre=len[1];
        }
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    linux 下使用scp命令传输文件
    yii2使用vendor文件夹下的的css文件
    yii2中使用定义在 params.php文件中的配置
    PHP Catchable fatal error: Argument 2 passed to IlluminateRoutingUrlGenerator::__construct()
    git 去除本地所有没有保存的修改
    学习修复Laravel The only supported ciphers are AES-128-CBC and AES-256-CBC
    [190308]Ubuntu 安装完之后,安装的软件小记
    swagger.yaml转换为swagger.json文件
    Linux sed -i 字符串替换
    [笔记]Laravel TDD 胡乱记录
  • 原文地址:https://www.cnblogs.com/xwww666666/p/11800382.html
Copyright © 2011-2022 走看看