zoukankan      html  css  js  c++  java
  • Get The Treasury【HDU-3642】【扫描线】

    题目链接

      题目给出的是N个体积块,问的是有多少体积重叠了3次及以上?

      那么就是怎么处理体积这样子的问题了,看到Z的种类不多的时候,就想着从Z离散化的角度去考虑这个问题了,然后就是怎样子去处理面积了,这时候想到每一个Z所代表的这个面对应上的体积,然后把每个面都处理出来看,体积就是在处理X的和,以及求Y、Z的差(差分)来的乘积,所以在处理Z上的时候也有些细节的东西,就是我们要考虑到目前所访问到的这个面积段是否是可以取的,也就是要去判断它的上下Z坐标和目前的区间的上下Z坐标的关系式了。

      另外,在处理pushup()的时候,也是需要注意细节,我在这里处理的是"≥times"也就是覆盖次数大于等于1的线段的长、大于等于2的线段的长……

    剩下的吧,基本就是写代码上的,细心点,没什么其他的了。

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <string>
    #include <cstring>
    #include <algorithm>
    #include <limits>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <set>
    #include <map>
    #define lowbit(x) ( x&(-x) )
    #define pi 3.141592653589793
    #define e 2.718281828459045
    #define INF 0x3f3f3f3f
    #define HalF (l + r)>>1
    #define lsn rt<<1
    #define rsn rt<<1|1
    #define Lson lsn, l, mid
    #define Rson rsn, mid+1, r
    #define QL Lson, ql, qr
    #define QR Rson, ql, qr
    #define myself rt, l, r
    using namespace std;
    typedef unsigned long long ull;
    typedef long long ll;
    const int maxN = 1e3 + 7;
    int N, X[maxN<<1], tot, Z[maxN<<1], cnt, lsan_Z, _UP;
    struct IOput
    {
        int lx, ly, lz, rx, ry, rz;
    }a[maxN];
    struct node
    {
        int lx, rx, y, val;
        node(int a=0, int b=0, int c=0, int d=0):lx(a), rx(b), y(c), val(d) {}
    }line[maxN<<1];
    bool cmp(node e1, node e2) { return e1.y < e2.y; }
    struct Tree
    {
        int siz, sum, len1, len2;   //求的是"≥times"的数的个数和
        void clear() { siz = sum = len1 = len2 = 0; }
    }t[maxN<<3];
    inline void buildTree(int rt, int l, int r)
    {
        t[rt].clear();
        if(l == r) return;
        int mid = HalF;
        buildTree(Lson);
        buildTree(Rson);
    }
    inline void pushup(int rt, int l, int r)
    {
        if(t[rt].siz >= 3)
        {
            t[rt].sum = t[rt].len2 = t[rt].len1 = X[r + 1] - X[l];
        }
        else if(t[rt].siz == 2)
        {
            t[rt].sum = t[lsn].len1 + t[rsn].len1;
            t[rt].len2 = t[rt].len1 = X[r + 1] - X[l];
        }
        else if(t[rt].siz == 1)
        {
            t[rt].sum = t[lsn].len2 + t[rsn].len2;
            if(l == r) t[rt].len2 = 0;  //相等的时候记得清空对应值
            else t[rt].len2 = t[lsn].len1 + t[rsn].len1;
            t[rt].len1 = X[r + 1] - X[l];
        }
        else if(l == r) t[rt].clear();
        else
        {
            t[rt].sum = t[lsn].sum + t[rsn].sum;
            t[rt].len2 = t[lsn].len2 + t[rsn].len2;
            t[rt].len1 = t[lsn].len1 + t[rsn].len1;
        }
    }
    inline void update(int rt, int l, int r, int ql, int qr, int val)
    {
        if(ql <= l && qr >= r)
        {
            t[rt].siz += val;
            pushup(myself);
            return;
        }
        int mid = HalF;
        if(qr <= mid) update(QL, val);
        else if(ql > mid) update(QR, val);
        else { update(QL, val); update(QR, val); }
        pushup(myself);
    }
    inline void init()
    {
        cnt = 0;
    }
    int main()
    {
        int T;  scanf("%d", &T);
        for(int Cas=1; Cas<=T; Cas++)
        {
            scanf("%d", &N);
            init();
            for(int i=1; i<=N; i++)
            {
                scanf("%d%d%d%d%d%d", &a[i].lx, &a[i].ly, &a[i].lz, &a[i].rx, &a[i].ry, &a[i].rz);
                Z[++cnt] = a[i].lz;
                Z[++cnt] = a[i].rz;
            }
            sort(Z + 1, Z + cnt + 1);
            lsan_Z = (int)(unique(Z + 1, Z + cnt + 1) - Z - 1);
            ll ans = 0;
            for(int u=1; u<lsan_Z; u++)
            {
                tot = 0;
                for(int i=1; i<=N; i++)
                {
                    if(a[i].lz <= Z[u] && a[i].rz > Z[u])   //不能计算前面已经算过的部分,就是存在头即尾的情况
                    {
                        line[++tot] = node(a[i].lx, a[i].rx, a[i].ly, 1);
                        X[tot] = a[i].lx;
                        line[++tot] = node(a[i].lx, a[i].rx, a[i].ry, -1);
                        X[tot] = a[i].rx;
                    }
                }
                sort(line + 1, line + tot + 1, cmp);
                sort(X + 1, X + tot + 1);
                _UP = (int)(unique(X + 1, X + tot + 1) - X - 1);
                memset(t, 0, sizeof(t));
                for(int i=1, l, r; i<tot; i++)
                {
                    l = (int)(lower_bound(X + 1, X + _UP + 1, line[i].lx) - X);
                    r = (int)(lower_bound(X + 1, X + _UP + 1, line[i].rx) - X - 1);
                    update(1, 1, _UP, l, r, line[i].val);
                    ans += (ll)(Z[u + 1] - Z[u]) * (ll)(line[i + 1].y - line[i].y) * (t[1].sum);
                }
            }
            printf("Case %d: %lld
    ", Cas, ans);
        }
        return 0;
    }
    /*
    1
    6
    1 0 0 2 2 2
    0 1 0 2 2 2
    0 0 1 2 2 2
    1 0 0 2 2 2
    0 1 0 2 2 2
    0 0 1 2 2 2
    ans = 4
    */
    View Code
  • 相关阅读:
    CQUOJ 10819 MUH and House of Cards
    CQUOJ 9920 Ladder
    CQUOJ 9906 Little Girl and Maximum XOR
    CQUOJ 10672 Kolya and Tandem Repeat
    CQUOJ 9711 Primes on Interval
    指针试水
    Another test
    Test
    二分图匹配的重要概念以及匈牙利算法
    二分图最大匹配
  • 原文地址:https://www.cnblogs.com/WuliWuliiii/p/10934718.html
Copyright © 2011-2022 走看看