Get The Treasury HDU - 3642(扫描线求三维面积交。。体积交)

题意:

。。。就是求体积交。。。

解析:

  把每一层z抽出来,计算面积交, 然后加起来即可。。!

去看一下 二维面积交的代码 再看看这个三维面积交的代码。。 down函数里 你发现了什么规律!!!

参考二维面积交:https://www.cnblogs.com/WTSRUVF/p/9274318.html

代码如下  

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#define mem(a, b) memset(a, b, sizeof(a))
using namespace std;
const int maxn = 8010, INF = 0x7fffffff;
typedef long long LL;
int X[maxn];

struct node{
    int l, r, w;
    int lx, rx, sum, lsum, llsum;
}Node[maxn];

struct edge{
    int lxx, rxx, y, z1, z2;
    int f;
}Edge[maxn*2];

int cmp(edge a, edge b)
{
    return a.y < b.y;
}

void build(int k, int ll, int rr)
{
    Node[k].l = ll, Node[k].r = rr;
    Node[k].w = Node[k].sum = Node[k].lsum = Node[k].llsum = 0;
    Node[k].lx = X[ll];
    Node[k].rx = X[rr];
    if(ll + 1 == rr) return;
    int m = (ll + rr) / 2;
    build(k*2, ll, m);
    build(k*2+1, m, rr);
}

void down(int k)
{
    int len = Node[k].rx - Node[k].lx;
    if(Node[k].w >= 3)
    {
        Node[k].sum = Node[k].lsum = Node[k].llsum = len;
    }
    else if(Node[k].w == 2)
    {
        Node[k].lsum = Node[k].llsum = len;
        if(Node[k].l + 1 == Node[k].r)
            Node[k].sum = 0;
        else
            Node[k].sum = Node[k*2].lsum + Node[k*2+1].lsum;
    }
    else if(Node[k].w == 1)
    {
        Node[k].lsum = len;
        if(Node[k].l + 1 == Node[k].r)
            Node[k].llsum = Node[k].sum = 0;
        else
        {
            Node[k].llsum = Node[k*2].lsum + Node[k*2+1].lsum;
            Node[k].sum = Node[k*2].llsum + Node[k*2+1].llsum;
        }
    }
    else
    {
        if(Node[k].l + 1 == Node[k].r)
            Node[k].sum = Node[k].lsum = Node[k].llsum = 0;
        else
        {
            Node[k].lsum = Node[k*2].lsum + Node[k*2+1].lsum;
            Node[k].llsum = Node[k*2].llsum + Node[k*2+1].llsum;
            Node[k].sum = Node[k*2].sum + Node[k*2+1].sum;
        }
    }

}

void update(int k, edge e)
{
    if(Node[k].lx == e.lxx && Node[k].rx == e.rxx)
    {
        Node[k].w += e.f;
        down(k);
        return;
    }
    if(e.rxx <= Node[k*2].rx) update(k*2, e);
    else if(e.lxx >= Node[k*2+1].lx) update(k*2+1, e);
    else
    {
        edge temp = e;
        temp.rxx = Node[k*2].rx;
        update(k*2, temp);
        temp = e;
        temp.lxx = Node[k*2+1].lx;
        update(k*2+1, temp);
    }
    down(k);
}

int main()
{
    int T, kase = 0;
    scanf("%d",&T);
    while(T--)
    {
        int n, cnt = 0;
        scanf("%d",&n);
        for(int i=0; i<n; i++)
        {
            int x1, y1, z1, x2, y2, z2;
            scanf("%d%d%d%d%d%d", &x1, &y1, &z1, &x2, &y2, &z2);
            Edge[++cnt].lxx = x1, Edge[cnt].rxx = x2, Edge[cnt].y = y1, Edge[cnt].f = 1, Edge[cnt].z1= z1, Edge[cnt].z2 = z2;
            X[cnt] = x1;
            Edge[++cnt].lxx = x1, Edge[cnt].rxx = x2, Edge[cnt].y = y2, Edge[cnt].f = -1, Edge[cnt].z1= z1, Edge[cnt].z2 = z2;
            X[cnt] = x2;
        }
        sort(Edge+1, Edge+cnt+1, cmp);
        sort(X+1, X+cnt+1);
        int m = unique(X+1, X+cnt+1) - (X+1);
        LL ret = 0;
        for(int i=-500; i<=500; i++)
        {
            build(1, 1, m);
            int ans = 0;
            edge line[maxn];
            for(int j=1; j<=cnt; j++)
            {
                if(Edge[j].z1 <= i && Edge[j].z2 > i)
                    line[++ans] = Edge[j];
            }
            for(int j=1; j<ans; j++)
            {
                update(1, line[j]);
                ret += (LL)Node[1].sum * (line[j+1].y - line[j].y);
            }
        }
        printf("Case %d: %lld\n",++kase,ret);

    }

    return 0;
}

 

posted @ 2018-07-06 19:58  WTSRUVF  阅读(256)  评论(0编辑  收藏  举报