您的位置:首页 > 其它

区间更新+区间统计——pku2777

2011-07-12 10:55 190 查看
统计一定区间内颜色的不同种数

开个hash,在search随时记录颜色数目

做完这题:

对线段树有了理解

更新操作时,线段树用遗传的方法,在一个区间异化时,将有用信息遗传到子代(仅仅是子代,不是所有的子孙都遗传,这样就节约了时间)

统计操作时,线段树用了区间统计(不是统计每个叶子),统计未被异化的区间(不是所有子孙都统计,又节约时间了)

对于函数参数的理解:

当传入的是结点下标n时,函数里考虑n+n,n+n+1的子树

而不仅传入有下标,还有区间时,就要分区间是在当前树的左子树,或是右子树,或是区间同时在左右子树

View Code

#include<stdio.h>

struct data
{
int l,r,val;
}node[300009];

bool hash[39];

inline int max(int a,int b)
{
return a>b?a:b;
}
void build(int ll,int rr,int n)
{
node
.l=ll;
node
.r=rr;
node
.val=1;
if (ll==rr) return ;
int mid=(ll+rr)/2;
build(ll,mid,2*n);
build(mid+1,rr,2*n+1);
}
void updata(int ll,int rr,int a,int n)
{

if(node
.val==a)return ;

if (node
.l==ll&&node
.r==rr)
{
node
.val=a;
return ;
}

if(node
.val!=-1)
{
node[n+n].val=node
.val;
node[n+n+1].val=node
.val;
node
.val=-1;
}

int mid=(node
.l+node
.r)/2;
if (rr<=mid) updata(ll,rr,a,2*n);
else if (ll>=mid+1) updata(ll,rr,a,2*n+1);
else
{
updata(ll,mid,a,2*n);
updata(mid+1,rr,a,2*n+1);
}

}

void search(int ll,int rr,int n)
{
if(node
.l<=ll&&node
.r>=rr&&node
.val!=-1)//所问区间在 已知结点的范围内,标记后,返回
{
hash[node
.val]=1;
return;
}
else
{
int mid=(node
.l+node
.r)/2;
if (rr<=mid) search(ll,rr,2*n);
else if (ll>mid) search(ll,rr,2*n+1);
else
{
search(ll,mid,2*n);
search(mid+1,rr,2*n+1);
}
}

}

int main()
{
int L,T,Q;
while(scanf("%d%d%d",&L,&T,&Q)!=EOF)
{
build(1,L,1);
char ss;
while(Q--)
{
getchar();
scanf("%c",&ss);

if(ss=='C')
{
int ll,rr,v;
scanf("%d%d%d",&ll,&rr,&v);
updata(ll,rr,v,1);
}
else
{
int ll,rr;
int i;
for(i=1;i<=T;i++)
{
hash[i]=0;
}
scanf("%d%d",&ll,&rr);
search(ll,rr,1);

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