线段树

1、Codeforces 377D Developing Game

解题思路:

参考:http://codeforces.com/blog/entry/10157

http://www.cnblogs.com/qscqesze/p/5541837.html

转化为扫描线问题

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <cmath>
#include <cctype>
#include <ctime>
#include <cassert>

using namespace std;

#define REP(i, n) for (int i = 0; i < (n); ++i)
#define eps 1e-6
#define PI acos(-1.0)
#define lc id << 1
#define rc id << 1 | 1
#define lson low, mid, lc
#define rson mid + 1, high, rc

typedef long long ll;
typedef pair<int, int> pii;
struct Node {
    int x, y1, y2, flag;
    bool operator < (const Node& a) const {
        if (x == a.x) { return flag > a.flag; } return x < a.x;
    }
};

const int INF = 0x7fffffff;
const int maxn = 6e5 + 10;
vector<int> y;
int n, id1, id2, Size, ans = 0, len_t, ans_l, ans_r, cnt = 0;
Node node[maxn];
int Left[maxn], v[maxn], Right[maxn], max_cnt[maxn * 4], max_r[maxn * 4], lazy[maxn * 4];

int id(int x) { return lower_bound(y.begin(), y.end(), x) - y.begin() + 1; }
void build(int low, int high, int id) {
    max_r[id] = y[high - 1]; if (low == high) { return; }
    int mid = (low + high) / 2; build(lson); build(rson);
}
inline void push_up(int id) {
    if (max_cnt[rc] >= max_cnt[lc]) { max_r[id] = max_r[rc]; } else { max_r[id] = max_r[lc]; }
    max_cnt[id] = max(max_cnt[lc], max_cnt[rc]);
}
inline void push_down(int id) {
    if (lazy[id] == 0) { return; } max_cnt[lc] += lazy[id]; lazy[lc] += lazy[id];
    max_cnt[rc] += lazy[id]; lazy[rc] += lazy[id]; lazy[id] = 0;
}
void update(int l, int r, int key, int low, int high, int id) {
    if (l == low && r == high) { max_cnt[id] += key; lazy[id] += key; return; }
    int mid = (low + high) / 2; push_down(id);
    if (r <= mid) { update(l, r, key, lson); }
    else if (l >= mid + 1) { update(l, r, key, rson); }
    else { update(l, mid, key, lson); update(mid + 1, r, key, rson); }
    push_up(id);
}

int main() {
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
//    freopen("out.txt", "w", stdout);
#endif // __AiR_H
    scanf("%d", &n);
    REP(i, n) {
        scanf("%d %d %d", &Left[i], &v[i], &Right[i]); y.push_back(v[i]); y.push_back(Right[i]);
        node[i * 2] = Node{Left[i], v[i], Right[i], 1}; node[i * 2 + 1] = Node{v[i], v[i], Right[i], -1};
    }
    sort(y.begin(), y.end()); y.erase(unique(y.begin(), y.end()), y.end());
    n *= 2; sort(node, node + n); Size = y.size(); build(1, Size, 1);
    REP(i, n) {
        id1 = id(node[i].y1); id2 = id(node[i].y2);
        update(id1, id2, node[i].flag, 1, Size, 1);
        if (max_cnt[1] > ans) { ans = max_cnt[1]; ans_l = node[i].x; ans_r = max_r[1]; }
    }
    printf("%d\n", ans);
    REP(i, n) {
        if (Left[i] <= ans_l && ans_r <= Right[i] && ans_l <= v[i] && v[i] <= ans_r) {
            printf(++cnt == 1 ? "%d" : " %d", i + 1);
        }
    }
    printf("\n");
#ifdef __AiR_H
    printf("Time used = %.2fs\n", (double)clock() / CLOCKS_PER_SEC);
#endif // __AiR_H
    return 0;
}

2、HDU 5722 Jewelry

参考:http://blog.csdn.net/jtjy568805874/article/details/51944740

PS:矩形变了样子,然后就不会求矩形并的面积了QwQ。。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <cmath>
#include <cctype>
#include <ctime>
#include <cassert>

using namespace std;

#define REP(i, n) for (int i = 0; i < (n); ++i)
#define eps 1e-6
#define PI acos(-1.0)
#define lc id << 1
#define rc id << 1 | 1
#define lson low, mid, lc
#define rson mid + 1, high, rc

typedef long long ll;
typedef pair<int, int> pii;
struct Node {
    int x, y1, y2, flag;
    bool operator < (const Node& a) const {
        if (x == a.x) { return flag > a.flag; } return x < a.x;
    }
};

const int INF = 0x7fffffff;
const int maxn = 2e5 + 10;
int T, n, x, A, N = 0;
ll ans = 0;
Node node[maxn];
int cnt[maxn * 4], len[maxn * 4];
vector<pii> v;

void build(int low, int high, int id) {
    cnt[id] = len[id] = 0; if (low == high) { return; }
    int mid = (low + high) / 2; build(lson); build(rson);
}
inline void push_up(int id, int low, int high) {
    if (cnt[id]) { len[id] = high - low + 1; return; }
    len[id] = len[lc] + len[rc];
}
void update(int l, int r, int key, int low, int high, int id) {
    if (l == low && r == high) {
        cnt[id] += key; if (low == high && cnt[id] == 0) { len[id] = 0; return; }
        push_up(id, low, high); return;
    }
    int mid = (low + high) / 2;
    if (r <= mid) { update(l, r, key, lson); }
    else if (l >= mid + 1) { update(l, r, key, rson); }
    else { update(l, mid, key, lson); update(mid + 1, r, key, rson); }
    push_up(id, low, high);
}

int main() {
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
//    freopen("out.txt", "w", stdout);
#endif // __AiR_H
    scanf("%d", &T);
    while (T--) {
        v.clear(); N = 0;
        scanf("%d %d", &n, &x); REP(i, n) { scanf("%d", &A); v.push_back(make_pair(A, i)); }
        sort(v.begin(), v.end()); int l1, r1, l2, r2;
        REP(i, n) {
            if (i - x + 1 < 0 || v[i].first != v[i - x + 1].first) { continue; }
            l1 = 0; r1 = v[i - x + 1].second; l2 = v[i].second; r2 = n - 1;
            if (i - x >= 0 && v[i - x].first == v[i].first) { l1 = v[i - x].second + 1; }
            if (i + 1 < n && v[i + 1].first == v[i].first) { r2 = v[i + 1].second - 1; }
            ++l1; ++r1; ++l2; ++r2;
            node[N++] = Node{l1, l2, r2, 1}; node[N++] = Node{r1, l2, r2, -1};
        }
        sort(node, node + N);  build(1, n, 1); ans = 0;
        for (int i = 0, j; i < N; i = j) {
            if (i > 0) { ans += (ll)(node[i].x - node[i - 1].x - 1) * len[1]; }
            j = i;
            while (j < N && node[j].x == node[i].x && node[j].flag == 1) {
                update(node[j].y1, node[j].y2, node[j].flag, 1, n, 1); ++j;
            }
            ans += len[1];
            while (j < N && node[j].x == node[i].x && node[j].flag == -1) {
                update(node[j].y1, node[j].y2, node[j].flag, 1, n, 1); ++j;
            }
        }
        printf("%I64d\n", ans);
    }
#ifdef __AiR_H
    printf("Time used = %.2fs\n", (double)clock() / CLOCKS_PER_SEC);
#endif // __AiR_H
    return 0;
}


















  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值