涂色问题,题意我就不说了。
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <string>
#include <math.h>
#define LL long long
#define maxn 200005
using namespace std;
struct Node
{
int color;
int left,right;
};
struct Node node[maxn*4];
int vis[31];
void build(int o,int L,int R) //建树
{
node[o].color=1; //初始为1
node[o].left=L;
node[o].right=R;
if(node[o].left==node[o].right)
return;
int M=(L+R)>>1;
build(o<<1,L,M);
build(o<<1|1,M+1,R);
}
void pushdown(int o) //LAZY操作
{
if(node[o].color>0)
{
node[o<<1].color=node[o<<1|1].color=node[o].color;
node[o].color=-1;
}
}
void update(int o,int L,int R,int c) //更新
{
if(L<=node[o].left && R>=node[o].right)
{
node[o].color=c; //上色
return;
}
pushdown(o);
int M=(node[o].left+node[o].right)>>1;
if(R<=M) //左子树
update(o*2,L,R,c);
else
{
if(L>M) //右子树
update(o*2+1,L,R,c);
else //左右子树都有的情况
{
update(o*2,L,M,c);
update(o*2+1,M+1,R,c);
}
}
}
void query(int o,int L,int R)
{
if(node[o].color>0)
{
vis[node[o].color]=1; //1表示这种颜色能看到,0表示不能
return;
}
if(node[o].left==node[o].right)
return;
int M=(node[o].left+node[o].right)>>1;
if(R<=M)
query(o*2,L,R);
else
{
if(L>M)
query(o*2+1,L,R);
else
{
query(o*2,L,M);
query(o*2+1,M+1,R);
}
}
}
int Getans(int t)
{
int ans=0;
for(int i=1;i<=t;i++)
if(vis[i]==1)
ans++;
return ans;
}
int main()
{
int len,t,o;
scanf("%d%d%d",&len,&t,&o);
build(1,1,len);
while(o--)
{
char ch;
getchar();
scanf("%c",&ch);
if(ch==‘C‘)
{
int ll,rr,c;
scanf("%d%d%d",&ll,&rr,&c);
if(ll>rr) //注意ll可能是大于rr的。题目中有说
update(1,rr,ll,c);
else
update(1,ll,rr,c);
}
else
{
int ll,rr;
memset(vis,0,sizeof(vis));
scanf("%d%d",&ll,&rr);
if(ll>rr)
query(1,rr,ll);
else
query(1,ll,rr);
printf("%d\n",Getans(t));
}
}
return 0;
}POJ2777(线段树区间更新+LAZY),布布扣,bubuko.com
原文:http://blog.csdn.net/mfmy_szw/article/details/21277467