您的位置:首页 > 其它

PKU 2777 【线段树】

2010-05-17 02:24 218 查看
统计的时候关键是看完全被覆盖的线段是否和目标线段有交,如果有交,则把标记数组中相应的颜色设为true,扫描一下标记数组就可以得到颜色个数。

代码#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;
const int MAXN = 100010;
int cnt;
bool flag = false;
bool ans[100];
int stNum;
struct node
{
int l;
int r;
int mid;
int c;
};
node seg_tree[MAXN*4];
void make(int num,int l,int r)
{
seg_tree[num].l = l;
seg_tree[num].r = r;
seg_tree[num].mid = (l+r)/2;
seg_tree[num].c = 1;
if (l+1!=r)
{
make(num*2,l,seg_tree[num].mid);
make(num*2+1,seg_tree[num].mid,r);
}
}
void insert(int num,int a,int b,int c)
{
if (seg_tree[num].c!=c)
{
if (seg_tree[num].l==a&&seg_tree[num].r==b)
{
seg_tree[num].c = c;
return;
}
if (seg_tree[num].c>=1)
{
seg_tree[2*num].c = seg_tree[num].c;
seg_tree[2*num+1].c = seg_tree[num].c;
seg_tree[num].c = -1;
}

if (b<=seg_tree[num].mid)
{
insert(2*num,a,b,c);
}
else if (a>=seg_tree[num].mid)
{
insert(2*num+1,a,b,c);
}
else
{
insert(2*num,a,seg_tree[num].mid,c);
insert(2*num+1,seg_tree[num].mid,b,c);
}
}
}
void cal(int num,int l,int r)
{
if(seg_tree[num].c>=1)
{
if(!(r<=seg_tree[num].l||l>=seg_tree[num].r))//关键:判断是否和目标线段相交
{
ans[seg_tree[num].c] = true;
}
return;
}
if(seg_tree[num].l+1!=seg_tree[num].r)
{
cal(2*num,l,r);
cal(2*num+1,l,r);
}
}
int main()
{

int l,t,o;
int a,b,c;
char op[4];
scanf("%d%d%d",&l,&t,&o);
make(1,1,l+1);
for (int i=0;i<o;i++)
{
scanf("%s",op);
if (op[0]=='C')
{
scanf("%d%d%d",&a,&b,&c);
if (a>b)
{
swap(a,b);
}
b++;
insert(1,a,b,c);
}
else
{

scanf("%d%d",&a,&b);
if (a>b)
{
swap(a,b);
}
b++;

flag = false;
memset(ans,false,sizeof(ans));
cal(1,a,b);
int res = 0;
for (int j=1;j<=t;j++)
{
if (ans[j])
{
res++;
}
}
printf("%d\n",res);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: