TreeSegment2777

题目大意:统计颜色。简单的说就是对长度为L的子单位区间着色。颜色最多为31种。用1~31表示。

现有两种操作:1,C,A,B,C表示将A~B区间着成C色。2,P,A,B表示询问A~B区间有多少种不同的颜色。

对于第二种操作输出其值。

思路:线段树 + lazy思想。

include<stdio.h>

#include<string.h>

#define SIZE 100010

typedef struct{

int left,right;

int flag;            //延迟标记

int color;            //位标记颜色

}info;

info segment[4 * SIZE];

void build_tree(int l,int r,int No);

void update(int l,int r,int No,int c);

void push_down(int No);

int query(int l,int r,int No);

int solve(int m);

int L,T,O;

int main()

{

char op;

int A,B,C;

while(~scanf("%d %d %d",&L,&T,&O)){

getchar();

build_tree(1,L,1);

while(O --){

op = getchar();

getchar();

switch(op){

case ‘C‘:

scanf("%d %d %d",&A,&B,&C);

update(A,B,1,C - 1);

break;

case ‘P‘:

scanf("%d %d",&A,&B);

printf("%d\n",solve( query(A,B,1) ) );

}

getchar();

}

}

return 0;

}

void build_tree(int l,int r,int No)

{

int mid = (l + r) >> 1;

segment[No].left = l;

segment[No].right = r;

segment[No].flag = 1;

segment[No].color = 1;

if( l == r ) return;

build_tree(l ,mid, No * 2);

build_tree(mid + 1 , r, No * 2 + 1);

}

void update(int l,int r,int No,int c)// update(A,B,1,C - 1);

{

int mid = (segment[No].left + segment[No].right) >> 1;

if( l == segment[No].left && r == segment[No].right ){

segment[No].color = 1 << c;

segment[No].flag = 1;

return;

}//如果不能完全匹配,那么就会造成状态不一致,那么在父节点状态全部一致的前提下,就要pushdown,把更新前的状态传给子节点

if( segment[No].flag ) push_down(No);

if( r <= mid ) update(l,r,No * 2,c);

else if( l >= mid + 1 ) update(l,r,No * 2 + 1,c);

else {

update(l,mid,No * 2 ,c);

update(mid + 1,r,No * 2 + 1,c);

}

segment[No].color = segment[No * 2].color | segment[No * 2 + 1].color;//pushup递归结束,修改父节点状态

}

void push_down(int No)

{

segment[No * 2].color = segment[No * 2 + 1].color = segment[No].color ;

segment[No * 2].flag = segment[No * 2 + 1].flag = 1;

segment[No].flag = 0;//父节点状态全部一致

}

int query(int l,int r,int No)//query(A,B,1)

{

int mid = (segment[No].left + segment[No].right) >> 1;

//完全匹配,或者根节点已经是状态全部一致,那么子节点就是父节点的状态

if( l == segment[No].left && r == segment[No].right  || segment[No].flag ){

return segment[No].color ;

}

if( r <= mid ) return query(l,r,No * 2);

if( l >= mid + 1 ) return query(l,r,No * 2 + 1);

return query(l,mid,No * 2) | query(mid + 1,r,No * 2 + 1);

}

int solve(int m)

{

int i;

int ans = 0;

for( i = 0; i < T;i ++ ){

if( m & (1 << i) ) ans ++;

}

return ans;

}

时间: 2024-12-18 07:46:47

TreeSegment2777的相关文章