ZOJ1610 线段树区间染色 ?

​​​​​​​​​​​​ZOJ1610​​​​​

为什么更新的时候r要-1啊啊啊啊

题意:

n次操作,每次对[l,r]染颜色d

问最后剩几个颜色,如果某个颜色有剩余则输出这个颜色 并输出其有几段

// Decline is inevitable,
// Romance will last forever.
//#include <bits/stdc++.h>
#include <iostream>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <deque>
#include <vector>
using namespace std;
#define mst(a, x) memset(a, x, sizeof(a))
#define INF 0x3f3f3f3f
//#define int long long
const int maxn = 1e4 + 10;
const int P = 1e9 + 7;
int n, q;
struct segment_tree {
    int l, r;
    int color;
#define color(x) tree[x].color
#define l(x) tree[x].l
#define r(x) tree[x].r
}tree[maxn << 2];
int t = 0;
void build(int p, int l, int r) {
    r(p) = r; l(p) = l;
    if(l == r) {
        color(p) = -1;
        return;
    }
    int mid = (l + r) >> 1;
    build(p<<1, l, mid);
    build(p<<1|1, mid + 1, r);
    color(p) = -1;
}
void spread(int p) {
    if(color(p) != -1) {
        color(p<<1) = color(p<<1|1) = color(p);
        color(p) = -1;
    }
    return;
}
void r_change(int p, int l, int r, int d) {
    if(l <= l(p) && r >= r(p)) {
        color(p) = d;
        return;
    }
    spread(p);
    int mid = (l(p) + r(p)) >> 1;
    if(l <= mid) r_change(p<<1, l, r, d);
    if(r > mid) r_change(p<<1|1, l, r, d);
}
int query(int p, int i) {
    if(color(p) != -1 && l(p)<=i && r(p) >= i) {
        return color(p);
    }
    if(l(p) == i && r(p) == i) return color(p);
    int mid = (l(p) + r(p)) >> 1;
    if(i <= mid) return query(p<<1, i);
    return query(p<<1|1, i);
}
int wall[10000];
int num[10000];
void solve() {
    while(cin >> n) {
        mst(tree, 0);
        mst(wall, 0);
        mst(num, 0);
        int mx = 0;
        build(1, 0, 8000);
        while(n--) {
            int l, r, d;
            cin >> l >> r >> d;
            r_change(1, l, r-1, d);
            mx = max(mx, r);
        }
        for(int i = 0; i <=mx; i++) {
            wall[i] = query(1, i);
        }
        for(int i = 0; i <= mx; i++) {
            if(wall[i] != wall[i+1] && wall[i] != -1) {
                num[wall[i]]++;
            }
        }
        for(int i = 0; i <= 8000; i++) {
            if(num[i]) cout << i << ' ' << num[i] << endl;
        }
        cout << endl;
    }
}
signed main() {
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
//    int T;
//    cin >> T;
//    while(T--)
        solve();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_59273843/article/details/120631580
今日推荐