• POJ 1151 Atlantis(经典的线段树扫描线,求矩阵面积并)


    求矩阵的面积并

    采用的是区间更新

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #define lson rt<<1,L,mid
    #define rson rt<<1|1,mid+1,R
    /*
    AC
    一开始一直WA的原因是,hashx写成了int型!!!
    
    第一次用的是直接单点更新,这次用区间更新写写看
    */
    using namespace std;
    const int maxn=105;
    int n;
    double x1,y1,x2,y2;
    //题目中有误,题目说的是(x1,y1)为矩形的左上端点,(x2,y2)为矩形的右下端点,
    //但是给出的值y1<y2。。。也就是说(x1,y1)为矩形的左下端点,(x2,y2)为矩形的右上端点
    double hashx[maxn<<1];
    int idx;
    int mark[maxn<<1];
    double sum[maxn<<1];
    struct Line{
        double y,l,r;
        int tp;
        bool operator<(const Line tmp)const{
            return y<tmp.y;
        }
    }line[maxn<<2];
    
    struct Node{
        double sum;
        int mark;
    }tree[maxn<<4];
    
    void build(int rt,int L,int R){
        tree[rt].sum=tree[rt].mark=0;
        if(L==R){
            return ;
        }
        int mid=(L+R)>>1;
        build(rt<<1,L,mid);
        build(rt<<1|1,mid+1,R);
    }
    
    void pushUp(int rt,int L,int R){
        if(tree[rt].mark){
            tree[rt].sum=hashx[R+1]-hashx[L];
        }
        else{
            if(L==R)
                tree[rt].sum=0;
            else
                tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;
        }
    }
    void update(int rt,int L,int R,int l,int r,int val){
        if(L==R){
            //原本写了个tree[rt].mark。。。
            tree[rt].mark+=val;
            pushUp(rt,L,R);
            return;
        }
        int mid=(L+R)>>1;
        if(r<=mid)
            update(lson,l,r,val);
        else if(l>mid)
            update(rson,l,r,val);
        else{
            update(lson,l,mid,val);
            update(rson,mid+1,r,val);
        }
        pushUp(rt,L,R);
    }
    //二分搜索对应的映射,也可以用map建立double-int的映射关系
    int binarySearch(double x){
        int l=0,r=n+1,mid;  //注意:l初试为0,r初试为n+1。否则若是1和n的话,若搜索的值为hashx[1]或者hashx[n]就错了。
        while (r-l>1)  //这里若为r>l的话,就会陷入死循环。举例:l=1,r=2,mid=1,x>=hashx[1]。
        {
            mid=(l+r)>>1;
            if (hashx[mid]<=x) l=mid;
                else r=mid;
        }
        return l;
    }
    
    int main()
    {
        int a,b,t=0;
        while(scanf("%d",&n),n){
            idx=0;
            t++;
            for(int i=1;i<=n;i++){
                scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
                line[2*i-1].y=y1;line[2*i-1].l=x1;line[2*i-1].r=x2;line[2*i-1].tp=1;
                line[2*i].y=y2;line[2*i].l=x1;line[2*i].r=x2;line[2*i].tp=-1;
                hashx[++idx]=x1;
                hashx[++idx]=x2;
            }
            n=n*2;
            build(1,1,n);
            sort(line+1,line+1+n);
            sort(hashx+1,hashx+idx+1);
            double ans=0;
            for(int i=1;i<=n;i++){
                ans+=tree[1].sum*(line[i].y-line[i-1].y);
                a=binarySearch(line[i].l);
                b=binarySearch(line[i].r)-1;
                update(1,1,n,a,b,line[i].tp);
            }
            printf("Test case #%d
    ",t);
            printf("Total explored area: %.2lf
    
    ",ans);
        }
        return 0;
    }
    View Code

    采用的是单点更新

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    /*
    AC
    */
    using namespace std;
    const int maxn=105;
    int n;
    double x1,y1,x2,y2;
    //题目中有误,题目说的是(x1,y1)为矩形的左上端点,(x2,y2)为矩形的右下端点,
    //但是给出的值y1<y2。。。也就是说(x1,y1)为矩形的左下端点,(x2,y2)为矩形的右上端点
    double hashx[maxn<<1];
    int idx;
    int mark[maxn<<1];
    double sum[maxn<<1];
    struct Line{
        double y,l,r;
        int tp;
        bool operator<(const Line tmp)const{
            return y<tmp.y;
        }
    }line[maxn<<2];
    
    struct Node{
        double sum;
        int mark;
    }tree[maxn<<4];
    
    void build(int rt,int L,int R){
        tree[rt].sum=tree[rt].mark=0;
        if(L==R){
            return ;
        }
        int mid=(L+R)>>1;
        build(rt<<1,L,mid);
        build(rt<<1|1,mid+1,R);
    }
    
    void pushUp(int rt){
        tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;
    }
    void update(int rt,int x,int L,int R,int val){
        if(L==R){
            tree[L].mark+=val;
            //mark[x]+=val;
            if(tree[L].mark)
                tree[rt].sum=hashx[x+1]-hashx[x];
            else
                tree[rt].sum=0;
            return;
        }
        int mid=(L+R)>>1;
        if(x<=mid)
            update(rt<<1,x,L,mid,val);
        else
            update(rt<<1|1,x,mid+1,R,val);
        pushUp(rt);
    }
    //二分搜索对应的映射,也可以用map建立double-int的映射关系
    int binarySearch(double x){
        int l=0,r=n+1,mid;  //注意:l初试为0,r初试为n+1。否则若是1和n的话,若搜索的值为hashx[1]或者hashx[n]就错了。
        while (r-l>1)  //这里若为r>l的话,就会陷入死循环。举例:l=1,r=2,mid=1,x>=hashx[1]。
        {
            mid=(l+r)>>1;
            if (hashx[mid]<=x) l=mid;
                else r=mid;
        }
        return l;
    }
    
    int main()
    {
        int a,b,t=0;
        while(scanf("%d",&n),n){
            idx=0;
            t++;
            memset(mark,0,sizeof(mark));
            for(int i=1;i<=n;i++){
                scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
                line[2*i-1].y=y1;line[2*i-1].l=x1;line[2*i-1].r=x2;line[2*i-1].tp=1;
                line[2*i].y=y2;line[2*i].l=x1;line[2*i].r=x2;line[2*i].tp=-1;
                hashx[++idx]=x1;
                hashx[++idx]=x2;
            }
            n=n*2;
            build(1,1,n);
            sort(line+1,line+1+n);
            sort(hashx+1,hashx+idx+1);
            double ans=0;
            for(int i=1;i<=n;i++){
                ans+=tree[1].sum*(line[i].y-line[i-1].y);
                a=binarySearch(line[i].l);
                b=binarySearch(line[i].r)-1;
                for(int j=a;j<=b;j++)
                    update(1,j,1,n,line[i].tp);
            }
            printf("Test case #%d
    ",t);
            printf("Total explored area: %.2lf
    
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    jbpm4.4使用的hibernate3如何兼容spring5.x及异常Caused by: java.lang.ClassNotFoundException: org.hibernate.impl.SessionImpl
    Caused by: java.lang.ClassNotFoundException: io.netty.resolver.AddressResolverGroup
    Caused by: java.lang.ClassNotFoundException: org.jboss.marshalling.ClassResolver
    Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.dataformat.yaml.YAMLFactory
    Redisson报错Caused by: java.lang.IllegalArgumentException: RIVER
    redis中StringRedisTemplate的setIfAbsent方法设置过期时间
    xshell下载
    mysql下载地址
    最小化可行产品MVP
    电梯演讲
  • 原文地址:https://www.cnblogs.com/chenxiwenruo/p/3722413.html
Copyright © 2020-2023  润新知