zoukankan      html  css  js  c++  java
  • hdu3255线段树扫描线

    题目链接

    了解题意之后,没有思路。。参考了别人的博客,这个题目的解题思路就是维护分量,

    将原来的一个长度分解成三个长度,然后加以维护,维护通过pushUp操作来完成,维

    护的步骤按照价格的高低。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int maxn=130010;//矩形个数
    struct edge{
        int x1,x2,y,s;
        int f;//1入,-1出
        edge(){}
        edge(int _x1,int _x2,int _y,int _s,int _f)
        {
            x1=_x1,x2=_x2,y=_y,
                s=_s,f=_f;
        }
        bool operator <(const edge &e)
        {
            if(y!=e.y)return y<e.y;
            return f>e.f;
        }
    };
    struct price{
        int id,p;
        bool operator<(const price &prc)const
        {
            return p<prc.p;
        }
    };
    price P[5];
    int nSgs;
    edge Sgs[maxn*2];
    int nX;
    int X[maxn*2];
    int len[maxn*4][4];
    int cnt[maxn*4][4];
    void build(int root,int l,int r)
    {
        len[root][1]=len[root][2]=len[root][3]=0;
        cnt[root][1]=cnt[root][2]=cnt[root][3]=0;
        if(l==r)return;
        int mid=(l+r)/2;
        build(root*2,l,mid);
        build(root*2+1,mid+1,r);
    }
    //三个分量随着扫描线的变化
    void pushUp(int root,int l,int r,int f,int p)
    {
        if(cnt[root][3]){
            len[root][3]=X[r+1]-X[l];
            len[root][2]=0;
            len[root][1]=0;
        }
        else if(cnt[root][2]){
            len[root][3]=len[root*2][3]+len[root*2+1][3];
            len[root][2]=X[r+1]-X[l]-len[root][3];
            len[root][1]=0;
        }
        else if(cnt[root][1]){
            len[root][3]=len[root*2][3]+len[root*2+1][3];
            len[root][2]=len[root*2][2]+len[root*2+1][2];
            len[root][1]=X[r+1]-X[l]-len[root][3]-len[root][2];
        }
        else {
            len[root][3]=len[root*2][3]+len[root*2+1][3];
            len[root][2]=len[root*2][2]+len[root*2+1][2];
            len[root][1]=len[root*2][1]+len[root*2+1][1];
        }
    }
    void update(int root,int L,int R,int f,int p,int l,int r)
    {
        if(L<=l&&r<=R){
            cnt[root][p]+=f;
            pushUp(root,l,r,f,p);
            return;
        }
        int mid=(l+r)/2;
        if(mid>=L)update(root*2,L,R,f,p,l,mid);
        if(mid<R)update(root*2+1,L,R,f,p,mid+1,r);
        pushUp(root,l,r,f,p);
    }
    int bin(int k,int X[],int n)
    {
        int l=0,r=n-1,mid;
        while(l<=r){
            mid=(l+r)/2;
            if(X[mid]==k)return mid;
            else if(X[mid]>k)r=mid-1;
            else l=mid+1;
        }
        return -1;
    }
    int myUnique(int X[],int n)//哈希之前要去重
    {
        int p=1;
        for(int i=1;i<n;i++){
            if(X[i]!=X[i-1])X[p++]=X[i];
        }
        return p;
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        int T;
        int p=0;
        scanf("%d",&T);
        while(T--){
            p++;
            nX=0,nSgs=0;
            int n,m;
            scanf("%d%d",&n,&m);
            for(int i=1;i<=m;i++){
                P[i].id=i;
                scanf("%d",&P[i].p);
            }
            sort(P+1,P+1+m);
            while(n--){
                int x1,y1,x2,y2,id;
                scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&id);
                X[nX++]=x1,X[nX++]=x2;
                int k;
                for(int i=1;i<=m;i++){
                    if(P[i].id==id)k=i;
                }
                Sgs[nSgs++]=edge(x1,x2,y1,k,1);
                Sgs[nSgs++]=edge(x1,x2,y2,k,-1);
            }
            sort(X,X+nX);
            sort(Sgs,Sgs+nSgs);
            nX=myUnique(X,nX);
            build(1,0,nX-1);
            long long tot=0;
            for(int i=0;i<nSgs-1;i++){
                int l=bin(Sgs[i].x1,X,nX);
                int r=bin(Sgs[i].x2,X,nX)-1;
                if(l<=r)
                update(1,l,r,Sgs[i].f,Sgs[i].s,0,nX-1);
                int l1=len[1][1],l2=len[1][2],l3=len[1][3];
                tot+=((long long)(l1*P[1].p+l2*P[2].p+l3*P[3].p))*(Sgs[i+1].y-Sgs[i].y);
            }
            printf("Case %d: %lld
    ",p,tot);
        }
        //while(1);
    }
    View Code

    参考资料

    http://www.cnblogs.com/lxjshuju/p/6956796.html

  • 相关阅读:
    linux 进入 GNOME X 界面
    POJ 3436 ACM Computer Factory (拆点+最大流)
    学习:EF(Entity Framwork)结构【转】
    .net上传Excel,解析Excel,导出CSV
    在Handler里面使用Session
    如何用JavaScript判断访问的来源是电脑还是手机,是什么浏览器?
    ASP.NET List泛型分页代码 【转】
    ASP.NET MVC中实现多个按钮提交的几种方法【转】
    清空数据库所有表,所有存储过程SQL语句
    可以不被浏览器拦截的弹出窗口
  • 原文地址:https://www.cnblogs.com/MalcolmMeng/p/8460083.html
Copyright © 2011-2022 走看看