您的位置:首页 > 其它

Hdu 4614 线段树

2013-08-29 21:02 253 查看
这题很精巧,可以转化成如下五个操作

1.放花:置0

2.清理:置1

3.清理的输出:查找1的个数

4.放花的输出:

1)查找0的个数

2)查找第k个0所在位置

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define N 50005
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define initial 0,n-1,1
#define pb push_back
#define mp make_pair
using namespace std;
int n,m;

struct segtree{
int  a0[N<<2],a1[N<<2],lazy[N<<2];
void up(int rt)
{
a0[rt]=a0[rt<<1]+a0[rt<<1|1];
a1[rt]=a1[rt<<1]+a1[rt<<1|1];
}
void build(int l,int r,int rt)
{   lazy[rt]=0;
if (l==r) {     a1[rt]=0;
a0[rt]=1;
return;
}

int mid=(l+r)>>1;
build(lson);
build(rson);
up(rt);
}

void fun(int rt,int op,int m)
{   if (op==1)
{      a0[rt]=m; a1[rt]=0; }
if (op==2)
{      a0[rt]=0; a1[rt]=m; }

lazy[rt]=op;
}
void down(int rt,int m)
{
if (lazy[rt])
{   fun(rt<<1,lazy[rt],m-(m>>1));
fun(rt<<1|1,lazy[rt],m>>1);
lazy[rt]=0;
}
}
void update(int L,int R,int op,int l,int r,int rt)
{   if (L<=l&&r<=R)
{   fun(rt,op,r-l+1);
return;
}
down(rt,r-l+1);
int mid=(l+r)>>1;
if (L<=mid) update(L,R,op,lson);
if (mid<R)  update(L,R,op,rson);
up(rt);
}
int find(int c,int l,int r,int rt)
{   if (l==r) return l;
down(rt,r-l+1);
int mid=(l+r)>>1;
int re;
if (a0[rt<<1]>=c) re=find(c,lson);else re=find(c-a0[rt<<1],rson);
up(rt);
return re;

}
int query(int L,int R,int op,int l,int r,int rt)
{   if (L<=l&&r<=R) {
if (op==0)return a0[rt];
if (op==1)return a1[rt];
}
down(rt,r-l+1);
int mid=(l+r)>>1;
int re=0;
if (L<=mid) re+=query(L,R,op,lson);
if (mid<R)  re+=query(L,R,op,rson);
up(rt);
return re;
}
}st;

void doit()
{   char ss[12];
int x,y,z;
scanf("%d%d",&n,&m);
st.build(initial);
while (m--)
{   scanf("%d%d%d",&x,&y,&z);
if (x==1)
{

int tmp,left,ans1,ans2;
if (y!=0) tmp=st.query(0,y-1,0,initial);else tmp=0;
left=st.query(y,n-1,0,initial);
if (left==0)  {printf("Can not put any one.\n"); continue;}
ans1=st.find(tmp+1,initial);
ans2=st.find(tmp+min(left,z),initial);
printf("%d %d\n",ans1,ans2);
st.update(ans1,ans2,2,initial);

}
if (x==2)
{   printf("%d\n",st.query(y,z,1,initial));
st.update(y,z,1,initial);
}
}

}

int main()
{   int cas;
scanf("%d",&cas);
while (cas--) {doit();printf("\n");}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: