线段树 2017.4.20

1、Codeforces 272C Dima and Staircase

解题思路:

区间更新

#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 <bitset>
#include <ctime>

using namespace std;

#define REP(i, n) for (ll i = 0; i < (n); ++i)
#define lson low, mid, _id<<1
#define rson mid+1, high, _id<<1|1

typedef long long ll;

const ll mod = 1e9 + 7;
const ll INF = 0x7fffffff;
const ll maxn = 1e5 + 10;

ll n, m, w, h, ans;
ll a[maxn];
ll tree[4*maxn], lazy[4*maxn];

void build(ll low, ll high, ll _id);
void push_up(ll _id);
void update(ll Left, ll Right, ll val, ll low, ll high, ll _id);
void push_down(ll _id);
ll query(ll Left, ll Right, ll low, ll high, ll _id);

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
#endif // __AiR_H
    scanf("%I64d", &n);
    for (ll i = 1; i <= n; ++i) {
        scanf("%I64d", &a[i]);
    }
    build(1, n, 1);
    scanf("%I64d", &m);
    while (m--) {
        scanf("%I64d %I64d", &w, &h);
        ans = query(1, w, 1, n, 1);
        printf("%I64d\n", ans);
        update(1, w, ans + h, 1, n, 1);
    }
    return 0;
}

ll query(ll Left, ll Right, ll low, ll high, ll _id)
{
    if (low == Left && high == Right) {
        if (lazy[_id]) {
            return lazy[_id];
        }
        return tree[_id];
    }
    push_down(_id);
    ll mid = (low + high) >> 1;
    if (Right <= mid) {
        return query(Left, Right, lson);
    } else if (Left > mid) {
        return query(Left, Right, rson);
    } else {
        return max(query(Left, mid, lson), query(mid + 1, Right, rson));
    }
    push_up(_id);
}

void update(ll Left, ll Right, ll val, ll low, ll high, ll _id)
{
    if (low == Left && high == Right) {
        tree[_id] = lazy[_id] = val;
        return;
    }
    push_down(_id);
    ll mid = (low + high) >> 1;
    if (Right <= mid) {
        update(Left, Right, val, lson);
    } else if (Left > mid) {
        update(Left, Right, val, rson);
    } else {
        update(Left, mid, val, lson), update(mid + 1, Right, val, rson);
    }
    push_up(_id);
}

void push_down(ll _id)
{
    if (lazy[_id]) {
        tree[_id] = lazy[_id];
        tree[_id<<1] = lazy[_id], tree[_id<<1|1] = lazy[_id];
        lazy[_id<<1] = lazy[_id], lazy[_id<<1|1] = lazy[_id];
        lazy[_id] = 0;
    }
}

void build(ll low, ll high, ll _id)
{
    if (low == high) {
        tree[_id] = a[low];
        return;
    }
    ll mid = (low + high) >> 1;
    build(lson), build(rson);
    push_up(_id);
}

void push_up(ll _id)
{
    tree[_id] = max(tree[_id<<1], tree[_id<<1|1]);
}


2、Codeforces 356A Knight Tournament

解题思路:

参考:http://www.cnblogs.com/dashuzhilin/p/4535178.html

刚开始写按照题目所给次序更新(写起来好麻烦的样子...调了好久), TLE on test 37 了...QAQ

后来看题解发现只要按照相反次序更新就可以了

#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 <bitset>
#include <ctime>

using namespace std;

#define REP(i, n) for (int i = 0; i < (n); ++i)
#define lson low, mid, _id<<1
#define rson mid+1, high, _id<<1|1

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef pair<int, int> Pair;

const ll mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 3e5 + 10;

int n, m, cnt = 0;
int l[maxn], r[maxn], x[maxn];
int lazy[4*maxn];

void update(int Left, int Right, int val, int low, int high, int _id);
void push_down(int _id);
void query(int low, int high, int _id);
void push_up(int _id);

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
#endif // __AiR_H
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= m; ++i) {
        scanf("%d %d %d", &l[i], &r[i], &x[i]);
    }
    for (int i = m; i >= 1; --i) {
        if (l[i] < x[i]) {
            update(l[i], x[i] - 1, x[i], 1, n, 1);
        }
        if (r[i] > x[i]) {
            update(x[i] + 1, r[i], x[i], 1, n, 1);
        }
    }
    query(1, n, 1);
    printf("\n");
    return 0;
}

void query(int low, int high, int _id)
{
    if (lazy[_id]) {
        for (int i = low; i <= high; ++i) {
            printf(++cnt == 1 ? "%d" : " %d", lazy[_id]);
        }
        return;
    }
    if (low == high) {
        printf(++cnt == 1 ? "0" : " 0");
        return;
    }
    int mid = (low + high) >> 1;
    query(lson), query(rson);
}

void update(int Left, int Right, int val, int low, int high, int _id)
{
    if (low == Left && Right == high) {
        lazy[_id] = val;
        return;
    }
    push_down(_id);
    int mid = (low + high) >> 1;
    if (Right <= mid) {
        update(Left, Right, val, lson);
    } else if (Left > mid) {
        update(Left, Right, val, rson);
    } else {
        update(Left, mid, val, lson), update(mid + 1, Right, val, rson);
    }
}

void push_down(int _id)
{
    if (lazy[_id]) {
        lazy[_id<<1] = lazy[_id], lazy[_id<<1|1] = lazy[_id];
        lazy[_id] = 0;
    }
}


3、ZOJ 2301 Color the Ball

离散化很优美啊!

#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-9
#define lson low, mid, _id << 1
#define rson mid + 1, high, _id << 1 | 1

typedef long long ll;
typedef pair<int, int> pii;
struct Node { int x, y, z; };

const int INF = 0x7fffffff;
const int maxn = 1e6;
int N;
int l[maxn], r[maxn], key[maxn];
char cmd[2];
int tree[maxn];
vector<int> v;
vector<pii> ans;

int id(int x) { return lower_bound(v.begin(), v.end(), x) - v.begin() + 1; }
void update(int Left, int Right, int color, int low, int high, int _id);
void query(int low, int high, int _id);
int real(int x) { return v[x - 1]; }

int main() {
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
//    freopen("out.txt", "w", stdout);
#endif // __AiR_H
    while (scanf("%d", &N) != EOF) {
        if (N <= 0) { printf("Oh, my god\n"); continue; }
        v.clear(); memset(tree, -1, sizeof(tree)); ans.clear();
        for (int i = 0; i < N; ++i) {
            scanf("%d %d %s", &l[i], &r[i], cmd);
            if (cmd[0] == 'w') { key[i] = 1; }
            else { key[i] = -1; }
            v.push_back(l[i]); v.push_back(r[i]);
            if (l[i] > 1) { v.push_back(l[i] - 1); } v.push_back(r[i] + 1);
        }
        sort(v.begin(), v.end());
        v.erase(unique(v.begin(), v.end()), v.end());
        for (int i = 0; i < N; ++i) { update(id(l[i]), id(r[i]), key[i], 1, (int)v.size(), 1); }
        query(1, (int)v.size(), 1);
        if ((int)ans.size() == 0) { printf("Oh, my god\n"); continue; }
        int Max = real(ans[0].second) - real(ans[0].first), ans_l = ans[0].first, ans_r = ans[0].second;
        int l_t = ans[0].first, r_t = ans[0].second;
        for (int i = 1; i < (int)ans.size(); ++i) {
            if (ans[i].first - 1 == ans[i - 1].second) {
                r_t = ans[i].second;
            } else {
                l_t = ans[i].first; r_t = ans[i].second;
            }
            if (real(r_t) - real(l_t) > Max) { Max = real(r_t) - real(l_t); ans_l = l_t; ans_r = r_t; }
        }
        printf("%d %d\n", real(ans_l), real(ans_r));
    }
#ifdef __AiR_H
    printf("Time used = %.2fs\n", (double)clock() / CLOCKS_PER_SEC);
#endif // __AiR_H
    return 0;
}

void query(int low, int high, int _id) {
    if (tree[_id]) {
        if (tree[_id] == 1) { ans.push_back(make_pair(low, high)); }
        return;
    }
    int mid = low + (high - low) / 2;
    query(lson); query(rson);
}

void update(int Left, int Right, int color, int low, int high, int _id) {
    if (tree[_id] == color) { return; }
    if (low == Left && high == Right) { tree[_id] = color; return; }
    int mid = low + (high - low) / 2;
    if (tree[_id]) { tree[_id << 1] = tree[_id]; tree[_id << 1 | 1] = tree[_id]; tree[_id] = 0; }
    if (Left > mid) { update(Left, Right, color, rson); }
    else if (Right <= mid) { update(Left, Right, color, lson); }
    else { update(Left, mid, color, lson); update(mid + 1, Right, color, rson); }
}


4、HDU 5306 Gorgeous Sequence

参考:

《区间最值操作与历史最值问题》杭州学军中学 吉如一

http://www.cnblogs.com/shenben/p/6641984.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-9
#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;

const int INF = 0x7fffffff;
const int maxn = 1e6 + 10;
int T, n, m, cmd, x, y, t;
int a[maxn], Max[maxn * 4], second[maxn * 4], num[maxn * 4];
ll sum[maxn * 4];

inline void push_up(int _id) {
    sum[_id] = sum[lc] + sum[rc]; Max[_id] = max(Max[lc], Max[rc]); num[_id] = 0;
    if (Max[_id] == Max[lc]) { num[_id] += num[lc]; }
    if (Max[_id] == Max[rc]) { num[_id] += num[rc]; }
    second[_id] = max(second[lc], second[rc]);
    if (Max[lc] != Max[rc]) { second[_id] = max(second[_id], min(Max[lc], Max[rc])); }
}
inline void push_down(int _id) {
    if (Max[_id] < Max[lc]) { sum[lc] += (ll)(Max[_id] - Max[lc]) * num[lc]; Max[lc] = Max[_id]; }
    if (Max[_id] < Max[rc]) { sum[rc] += (ll)(Max[_id] - Max[rc]) * num[rc]; Max[rc] = Max[_id]; }
}
void build(int low, int high, int _id) {
    if (low == high) { Max[_id] = a[low]; sum[_id] = a[low]; num[_id] = 1; second[_id] = 0; return; }
    int mid = (low + high) / 2; build(lson); build(rson); push_up(_id);
}
int query_max(int Left, int Right, int low, int high, int _id) {
    if (low == Left && high == Right) { return Max[_id]; }
    int mid = (high + low) / 2; push_down(_id);
    if (Right <= mid) { return query_max(Left, Right, lson); }
    else if (Left >= mid + 1) { return query_max(Left, Right, rson); }
    else { return max(query_max(Left, mid, lson), query_max(mid + 1, Right, rson)); }
}
ll query_sum(int Left, int Right, int low, int high, int _id) {
    if (low == Left && high == Right) { return sum[_id]; }
    int mid = (high + low) / 2; push_down(_id);
    if (Right <= mid) { return query_sum(Left, Right, lson); }
    else if (Left >= mid + 1) { return query_sum(Left, Right, rson); }
    else { return query_sum(Left, mid, lson) + query_sum(mid + 1, Right, rson); }
}
void update(int Left, int Right, int key, int low, int high, int _id) {
    if (key >= Max[_id]) { return; }
    if (low == high) { sum[_id] += (ll)key - Max[_id]; Max[_id] = key; return; }
    if (Left == low && Right == high && key > second[_id]) {
        sum[_id] += (ll)num[_id] * (key - Max[_id]); Max[_id] = key; return;
    }
    int mid = (low + high) / 2; push_down(_id);
    if (Right <= mid) { update(Left, Right, key, lson); }
    else if (Left >= mid + 1) { update(Left, Right, key, rson); }
    else { update(Left, mid, key, lson); update(mid + 1, Right, 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", &T);
    while (T--) {
        scanf("%d %d", &n, &m);
        for (int i = 1; i <= n; ++i) { scanf("%d", &a[i]); }
        build(1, n, 1);
        while (m--) {
            scanf("%d %d %d", &cmd, &x, &y);
            if (cmd == 1) { printf("%d\n", query_max(x, y, 1, n, 1)); }
            else if (cmd == 2) { printf("%I64d\n", query_sum(x, y, 1, n, 1)); }
            else {
                scanf("%d", &t); update(x, y, t, 1, n, 1);
            }
        }
    }
#ifdef __AiR_H
    printf("Time used = %.2fs\n", (double)clock() / CLOCKS_PER_SEC);
#endif // __AiR_H
    return 0;
}


5、Codeforces 444C DZY Loves Colors

参考:

《小清新线段树》吉如一


http://blog.csdn.net/kalilili/article/details/46038733

#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-9
#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;

const int INF = 0x7fffffff;
const int maxn = 1e5 + 10;
int lazy[maxn * 4];
ll add[maxn * 4], sum[maxn * 4];
ll t;
int n, m, l, r, x, type;

inline void push_up(int _id) {
    sum[_id] = sum[lc] + sum[rc];
    if (lazy[lc] == lazy[rc]) { lazy[_id] = lazy[lc]; }
}
void build(int low, int high, int _id) {
    if (low == high) { lazy[_id] = low; return; }
    int mid = low + (high - low) / 2; build(lson); build(rson);
}
inline void push_down(int _id, int low, int mid, int high) {
    if (lazy[_id] == 0) { return; }
    add[lc] += add[_id]; sum[lc] += add[_id] * (mid - low + 1);
    add[rc] += add[_id]; sum[rc] += add[_id] * (high - mid);
    add[_id] = 0;
    lazy[lc] = lazy[_id]; lazy[rc] = lazy[_id]; lazy[_id] = 0;
}
void update(int Left, int Right, int key, int low, int high, int _id) {
    if (low == high) { sum[_id] += abs(lazy[_id] - key); lazy[_id] = key; return; }
    if (Left == low && high == Right && lazy[_id]) {
        t = abs(lazy[_id] - key); add[_id] += t; lazy[_id] = key;
        sum[_id] += t * (high - low + 1); return;
    }
    int mid = low + (high - low) / 2; push_down(_id, low, mid, high);
    if (Right <= mid) { update(Left, Right, key, lson); }
    else if (Left >= mid + 1) { update(Left, Right, key, rson); }
    else { update(Left, mid, key, lson); update(mid + 1, Right, key, rson); }
    push_up(_id);
}
ll query(int Left, int Right, int low, int high, int _id) {
    if (Left == low && Right == high) { return sum[_id]; }
    int mid = low + (high - low) / 2; push_down(_id, low, mid, high);
    if (Right <= mid) { return query(Left, Right, lson); }
    else if (Left >= mid + 1) { return query(Left, Right, rson); }
    else { return query(Left, mid, lson) + query(mid + 1, Right, rson); }
}

int main() {
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
//    freopen("out2.txt", "w", stdout);
#endif // __AiR_H
    scanf("%d %d", &n, &m);
    build(1, n, 1);
    while (m--) {
        scanf("%d %d %d", &type, &l, &r);
        if (type == 1) {
            scanf("%d", &x); update(l, r, x, 1, n, 1);
        } else {
            printf("%I64d\n", query(l, r, 1, n, 1));
        }
    }
#ifdef __AiR_H
    printf("Time used = %.2fs\n", (double)clock() / CLOCKS_PER_SEC);
#endif // __AiR_H
    return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值