其他分享
首页 > 其他分享> > ZOJ - 1610 Count the Colors(线段树区间颜色更新)

ZOJ - 1610 Count the Colors(线段树区间颜色更新)

作者:互联网

题目链接

思路:
先建树,lazy延迟数组,ans记录每个数字颜色出现次数,-1表示无色,-2表示多色,>=0表示有颜色。
Bulid函数只是将左右节点固定了,
PushUp更新父节点函数:当两个子节点颜色不同,则更新为-2,若相同则更新为子节点颜色,
PushDown更新子节点的lazy数组,子节点的lazy和tree.w值都更新为父节点的lazy,父节点lazy变为无色-1。
Update:
1.节点的左、右区间在修改区间之内,直接更新tree[idx].w和lazy[idx]为k
2.若此时不是1的情况,就需要PushDown将lazy数组往下推更新子节点才能继续更新子节点,更新完子节点还要PushUp
Query:查询所有颜色次数的值ans[i],用now_col记录上一次的颜色
1.若tree[idx].w == -1代表这棵子树所有节点都为-1无色,
2.若tree[idx].w >= 0 表示这棵子树所有节点都是一个相同的颜色,直接判断更新ans[i],
3.若tree[idx].w == -2表示该子树有多种颜色,要查询其子节点,查询两个子节点前要PushDown和PushDown

代码:

#include <bits/stdc++.h>
#define fastio ios::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL)
#define debug(a) cout << "debug : " << (#a) << " = " << a << endl

using namespace std;

typedef long long ll;
typedef pair<int, int> PII;

const int N = 8010;
const int INF = 0x3f3f3f3f;
const double eps = 1e-6;
const int mod = 1e9 + 7;

int n, m, now_col;
struct node
{
    int l, r, w;
} tree[N << 2];
int lazy[N << 2], ans[N];

inline void PushUp(int idx)
{
    if (tree[idx << 1].w == tree[idx << 1 | 1].w)
        tree[idx].w = tree[idx << 1].w;
    else
        tree[idx].w = -2;
}

inline void PushDown(int idx)
{
    if (lazy[idx] != -1)
    {
        lazy[idx << 1] = lazy[idx];
        lazy[idx << 1 | 1] = lazy[idx];
        tree[idx << 1].w = lazy[idx];
        tree[idx << 1 | 1].w = lazy[idx];
        lazy[idx] = -1;
    }
}

void Build(int idx, int l, int r)
{
    tree[idx].l = l, tree[idx].r = r;
    if (l == r)
        return;
    int mid = (l + r) / 2;
    Build(idx << 1, l, mid);
    Build(idx << 1 | 1, mid + 1, r);
}

inline void Update(int idx, int l, int r, int k)
{
    if (tree[idx].l >= l && tree[idx].r <= r)
    {
        tree[idx].w = k;
        lazy[idx] = k;
        return;
    }
    PushDown(idx);
    if (tree[idx << 1].r >= l)
        Update(idx << 1, l, r, k);
    if (tree[idx << 1 | 1].l <= r)
        Update(idx << 1 | 1, l, r, k);
    PushUp(idx);
}

inline void Query(int idx, int l, int r)
{
    if (tree[idx].w == -1)
    {
        now_col = -1;
        return;
    }
    else if (tree[idx].w >= 0)
    {
        if (tree[idx].w != now_col)
            ans[tree[idx].w]++;
        now_col = tree[idx].w;
    }
    else
    {
        int mid = l + r >> 1;
        PushDown(idx);
        PushUp(idx);
        Query(idx << 1, l, mid);
        Query(idx << 1 | 1, mid + 1, r);
    }
}
int main()
{
    fastio;
    while (cin >> n)
    {
        memset(tree, -1, sizeof tree), memset(lazy, -1, sizeof lazy), memset(ans, 0, sizeof ans);
        Build(1, 0, N);
        int Max = -1;
        for (int i = 1; i <= n; i++)
        {
            int l, r, k;
            cin >> l >> r >> k;
            Max = max(Max, k);
            Update(1, l + 1, r, k);
        }
        now_col = -1;
        Query(1, 0, N);
        for (int i = 0; i <= Max; i++)
            if (ans[i] != 0)
                cout << i << ' ' << ans[i] << endl;
        cout << endl;
    }

    return 0;
}

标签:Count,lazy,idx,int,ZOJ,tree,1610,更新,节点
来源: https://blog.csdn.net/Lucky12138/article/details/120421276