【扫描线】【线段树】UVa11983 Weird Advertisement

各种暴力 微笑


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;
const int Lmax = 60005;

struct Line {
    int x, down, up;
    int cover;
    bool operator < (const Line &b) const { return x < b.x; }
}L[Lmax];
int h[Lmax];
int N, K;

#define lc (u << 1)
#define rc (u << 1 | 1)

namespace SegmentTree {
    int cover[Lmax << 2]; long long len[Lmax << 2][11];
    
    inline void PushUp(int u, int l, int r)
    {
        for (int i = 0; i <= K; ++ i) len[u][i] = 0ll;
        if (l == r) {
            int cnt = min(K, cover[u]);
            len[u][cnt] = h[l] - h[l - 1];
        } else {
            for (int i = 0; i <= K; ++ i) {
                int cnt = min(K, cover[u] + i);
                len[u][cnt] += len[lc][i] + len[rc][i];
            }
        }
    }
    
    inline void build(int u, int l, int r)
    {
        cover[u] = 0;
        int mid = (l + r) >> 1;
        if(l ^ r) { build(lc, l, mid); build(rc, mid + 1, r); }
        PushUp(u, l, r);
    }
    
    inline void Add(int u, int l, int r, int L, int R, const int &c)
    {
        if (l == L && r == R) {
            cover[u] += c;
            PushUp(u, l, r); return;
        }
        int mid = (l + r) >> 1;
        if (R <= mid) Add(lc, l, mid, L, R, c);
        else if (L > mid) Add(rc, mid + 1, r, L, R, c);
        else {
            Add(lc, l, mid, L, mid, c);
            Add(rc, mid + 1, r, mid + 1, R, c);
        }
        PushUp(u, l, r);
    }
}

inline long long solve()
{
    cin >> N >> K;
    int x1, x2, y1, y2; int M = 0;
    for (int i = 1; i <= N; ++ i) {
        cin >> x1 >> y1 >> x2 >> y2;
        L[M] = (Line) { x1, y1, y2 + 1, 1 };
        h[M ++] = y1;
        L[M] = (Line) { x2 + 1, y1, y2 + 1, -1 };
        h[M ++] = y2 + 1;
    }
    sort(h, h + M);
    N = (int) (unique(h, h + M) - h);
    sort(L, L + M); -- M;
    
    long long ans = 0ll;
    using namespace SegmentTree; build(1, 1, N - 1);
    for (int i = 0; i < M; ++ i) {
        int l = (int) (lower_bound(h, h + N, L[i].down) - h + 1);
        int r = (int) (lower_bound(h, h + N, L[i].up) - h);
        Add(1, 1, N - 1, l, r, L[i].cover);
        ans += len[1][K] * (L[i + 1].x - L[i].x);
    }
    return ans;
}

int main()
{
    ios :: sync_with_stdio(false);
    int T; cin >> T;
    for (int cas = 1; cas <= T; ++ cas) printf("Case %d: %lld\n", cas, solve());
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值