您的位置:首页 > 其它

hdu 4614 Vases and Flowers(线段树:成段更新)

2013-07-29 20:59 387 查看
线段树裸题。自己写复杂了,准确说是没想清楚就敲了。

先是建点为已插花之和,其实和未插花是一个道理,可是开始是小绕,后来滚雪球了,跪了。

重新建图,分解询问1为:找出真正插画的开始点和终止点,做成段更新。

再次向notonlysuccess大神致谢,清晰的代码+清晰的思路=ac

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

const int MAXN=55555;
int sum[MAXN<<2];
int lag[MAXN<<2];
int n;

void PushUp(int rt)
{
if(lag[rt<<1]==lag[rt<<1|1]&&lag[rt<<1]!=-1)
lag[rt]=lag[rt<<1];
else
lag[rt]=-1;
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}

void PushDown(int rt,int m)
{
if(lag[rt]!=-1){
lag[rt<<1]=lag[rt<<1|1]=lag[rt];
sum[rt<<1]=(m-(m>>1))*(1-lag[rt]);
sum[rt<<1|1]=(m>>1)*(1-lag[rt]);
lag[rt]=-1;

}
}

void Build(int l,int r,int rt)
{
lag[rt]=-1;
if(l==r){
sum[rt]=1;
return ;
}
int m=(l+r)>>1;
Build(lson);
Build(rson);
PushUp(rt);
}

void updata(int L,int R,int c,int l,int r,int rt)
{
if(L<=l&&r<=R){
sum[rt]=(r-l+1)*(1-c);
lag[rt]=c;
return ;
}
PushDown(rt,r-l+1);
int m=(l+r)>>1;
if(L<=m)updata(L,R,c,lson);
if(m<R)updata(L,R,c,rson);
PushUp(rt);
}

int Query1(int L,int R,int l,int r,int rt)
{
if(L>R)
return 0;
if(L<=l&&r<=R)
return sum[rt];
PushDown(rt,r-l+1);
int m=(l+r)>>1;
int res=0;
if(L<=m)
res+=Query1(L,R,lson);
if(m<R)
res+=Query1(L,R,rson);
return res;
}

int Query2(int p,int l,int r,int rt)
{
if(l==r)
return l;
PushDown(rt,r-l+1);
int m=(l+r)>>1;
if(p<=sum[rt<<1])
return Query2(p,lson);
else
return Query2(p-sum[rt<<1],rson);
}
int main()
{
int T,m;
int op,a,b,k;
int flag=0;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);

Build(0,n-1,1);

for(k=0;k<m;k++)
{
scanf("%d%d%d",&op,&a,&b);

if(op==1){
int s=Query1(a,n-1,0,n-1,1);
if(!s)
printf("Can not put any one.\n");
else {
int left=Query1(0,a-1,0,n-1,1);

int l=Query2(left+1,0,n-1,1);
int r=Query2(left+min(s,b),0,n-1,1);
printf("%d %d\n",l,r);
updata(l,r,1,0,n-1,1);
}
}else {
printf("%d\n",b-a+1-Query1(a,b,0,n-1,1));
updata(a,b,0,0,n-1,1);
}
}
printf("\n");
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: