HDU 1698 Just a Hook
P2161 [SHOI2009]会场预约
本来是把区间染色放到第一次总结的,但是后来才发现自己对区间染色并没有那么熟练,所以特意提取出来总结一遍。
区间染色的查询主要有两种:一种是直接询问[L,R]之间的颜色种类,还有就是对每个颜色有一定的权值,求[L,R]之前的权值和
第一道题就是根据颜色的权值求区间和,第二种就是询问颜色种类个数
写第一道题的时候几乎是秒杀,当时思路很清晰,对杂色标记的向上传递处理的很好,一遍AC
关键在于push_up上,每次push_up要根据儿子节点的颜色来考虑是不是要打上-1(即杂色)的标记,还有查询的时候对于虽然完全覆盖但仍是杂色的节点应该继续往下搜索。
HDU 1698 Just a Hook
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 1e5+10;
int tree[maxn<<2]; //-1,0,1,2分别表示杂色,铜,银,金
int n,q;
void push_down(int id)
{
if(tree[id]==-1) return; //杂色是不能往下传递的
tree[id<<1] = tree[id<<1|1] = tree[id];
}
void push_up(int id)
{
//主要是看父节点会不会因为子节点更新 而变成杂色
if(tree[id<<1]==-1) tree[id]=-1;
if(tree[id<<1|1]==-1) tree[id]=-1;
if(tree[id<<1]!=tree[id<<1|1]) tree[id]=-1;
}
void update(int id,int stl,int str,int l,int r,int val)
{
if(stl==l && str==r)
{
tree[id] = val;
return ;
}
push_down(id);
int mid = (stl+str)>>1;
if(r<=mid) update(id<<1