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