• codevs 3044 矩形面积求并


    扫描线算法。这是一棵真.线段树。其实每个叶子节点记录[n,n+1)的信息即可。具体实现参见代码中神奇的-1。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define maxn 10005
    using namespace std;
    struct tree
    {
    int left,right,q;
    double sum;
    }node[maxn];
    struct seg
    {
    double x1,x2,h;
    int flag;
    }s[5005];
    int n,father[maxn];
    double q,w,e,z,hash[10005];
    double ans;
    bool cmp(seg x,seg y)
    {
    return x.h<y.h;
    }
    void build(int i,int left,int right)
    {
    node[i].left=left;
    node[i].right=right;
    node[i].sum=0;
    node[i].q=0;
    if (left==right)
    {
    father[left]=i;
    return;
    }
    else
    {
    int mid=(left+right)>>1;
    i=i<<1;
    build(i,left,mid);
    build(i+1,mid+1,right);
    }
    }
    int find(double x)
    {
    int l,r;
    l=1;r=2*n;
    for(;;)
    {
    int mid=(l+r)>>1;
    if (hash[mid]==x) return mid;
    else if (hash[mid]<x) l=mid+1;
    else r=mid-1;
    }
    }
    void pushup(int i)
    {
    int left=node[i].left,right=node[i].right;
    if (node[i].q>0) node[i].sum=hash[right+1]-hash[left];
    else if (left==right) node[i].sum=0;
    else node[i].sum=node[i<<1].sum+node[i<<1|1].sum;
    }
    void modify(int i,int l,int r,int flag)
    {
    int left=node[i].left,right=node[i].right;
    if ((l==left) && (r==right))
    {
    node[i].q=node[i].q+flag;
    pushup(i);
    return;
    }
    int mid=(left+right)>>1;
    if (r<=mid) modify(i<<1,l,r,flag);
    else if (l>=mid+1) modify(i<<1|1,l,r,flag);
    else
    {
    modify(i<<1,l,mid,flag);
    modify(i<<1|1,mid+1,r,flag);
    }
    pushup(i);
    }
    int main()
    {
    while (scanf("%d",&n)==1)
    {
    if (n==0) break;
    ans=0;
    build(1,1,2*n);
    for (int i=1;i<=n;i++)
    {
    scanf("%lf%lf%lf%lf",&q,&w,&e,&z);
    s[i*2-1].x1=q;s[i*2-1].x2=e;s[i*2-1].h=w;s[i*2-1].flag=1;
    s[i*2].x1=q;s[i*2].x2=e;s[i*2].h=z;s[i*2].flag=-1;
    hash[i*2-1]=q;hash[i*2]=e;
    }
    sort(s+1,s+n*2+1,cmp);
    sort(hash+1,hash+n*2+1);
    for (int i=1;i<=n*2-1;i++)
    {
    int ll=find(s[i].x1),rr=find(s[i].x2)-1;
    modify(1,ll,rr,s[i].flag);
    ans=ans+node[1].sum*(s[i+1].h-s[i].h);
    }
    printf("%.2lf ",ans);
    }
    return 0;
    }

  • 相关阅读:
    c# Action,Func,Predicate委托
    c# 匿名方法
    IIS网站无法启动,提示 另一个程序正在使用此文件
    c# Http下载
    mciSendString详解(转)
    【NOIP2006PJ】数列(sequence)题解
    2020.04.29【NOIP普及组】模拟赛C组30总结
    【USACO 2019 December Silver】Milk Visits题解
    【USACO 2019 February Bronze】Measuring Traffic 题解
    【USACO 2019 February Bronze】Measuring Traffic 题解
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/5180603.html
Copyright © 2020-2023  润新知