線段樹的lazy操作
線段樹,是一個滿的二叉樹,每次每一個子節點都是父節點的一半。所以二叉樹的每個節點都維護了一個區間。可是實現快速的查詢。
對於更新來講的話,如果每次都更新到最下面的節點,會非常的耗時間。所以假如更新到某個節點的時候,而這個節點的左右段和要更新的最有端點一致的話,就可以僅更新該節點,並在他的子節點上面(兩個)加上一個lazy-tag,不再往子節點更新值。如果以后更新到加lazy-tag標記的結點時,則需要把這個標記的值更新下去,並且在他的子節點跟新lazy-tag標記,並取消這個節點的lazy-tag。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<set>
#include<queue>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
#define inf 0x3f3f3f
#define MAXN 100100
struct tree
{
int l;
int r;
int colr;
bool lazy;//lazy是lazy-tag
};
tree t[MAXN*4];
int L,T,O;
int cc;
int x,y,c;
void Swap()
{
int temp=x;
x=y;
y=temp;
}
void Build(int l,int r,int index)
{
t[index].l=l;
t[index].r=r;
t[index].colr=1;
t[index].lazy=0;//lazy=0,說明當前結點沒有lazy標記。
if(l==r)
return;
int mid=(l+r)>>1;
Build(l,mid,index<<1);
Build(mid+1,r,index<<1|1);
}
void inse(int l,int r,int index,int cl)
{
if(t[index].l==l && t[index].r==r)
{
t[index].colr=(1<<(cl-1));
t[index].lazy=1;//更新到相應節點的時候,加上lazy-tag
return;
}
if(t[index].lazy) //如果當前的節點有lazy標記,則
{
t[index].lazy=0;//1,需要取消lazy標記,
t[index<<1].lazy=1;//2,往子節點傳遞lazy標記
t[index<<1|1].lazy=1;
t[index<<1].colr=t[index].colr;//3,並傳遞值
t[index<<1|1].colr=t[index].colr;
}
int mid=(t[index].l+t[index].r)>>1;
if(r<=mid)
inse(l,r,index<<1,cl);
else if(l>mid)
inse(l,r,index<<1|1,cl);
else
{
inse(l,mid,index<<1,cl);
inse(mid+1,r,index<<1|1,cl);
}
t[index].colr=t[index<<1].colr | t[index<<1|1].colr;//往上更新值。
}
void quer(int l,int r,int index)
{
//如果遇見帶lazy標記的節點,只需要返回當前的節點的值就行了,
if(t[index].lazy || (t[index].l==l && t[index].r==r) )
{
cc|=t[index].colr;
return;
}
int mid=(t[index].l+t[index].r)>>1;
if(r<=mid)
quer(l,r,index<<1);
else if(l>mid)
quer(l,r,index<<1|1);
else
{
quer(l,mid,index<<1);
quer(mid+1,r,index<<1|1);
}
}
int main()
{
while(scanf("%d%d%d",&L,&T,&O)!=EOF)
{
char ss;
Build(1,L,1);
while(O--)
{
scanf(" %c",&ss);
if(ss=='C')
{
scanf("%d%d%d",&x,&y,&c);
if(x>y)
Swap();
inse(x,y,1,c);
}
else
{
int ans=0;
scanf("%d%d",&x,&y);
if(x>y)
Swap();
cc=0;
quer(x,y,1);
for(int i=0; i<T; i++)
{
if(cc&(1<<i))
ans++;
}
printf("%d\n",ans);
}
}
}
return 0;
}