bzoj 1230 线段树 标签

来源:互联网 发布:备案的是域名还是主机 编辑:程序博客网 时间:2024/06/07 02:31

题意:n个灯,m个操作,初始灯全是关的。两种操作:(1)0 l r 把l到r的灯全部取反(开了的关掉,关了的打开)(2) 1 l r 询问[l,r]开着的灯的个数

一眼看过去就是线段树,没毛病

对于修改,相当于每个数取异或,打标签处理一下就好了

type        rec=record            l,r,sum:longint;            flag:boolean;end;var        n,m,op,x,y      :longint;        i               :longint;        t               :array[0..400010] of rec;procedure build(x,l,r:longint);var        mid:longint;begin   t[x].l:=l; t[x].r:=r;   if l=r then exit;   mid:=(l+r)>>1;   build(2*x,l,mid); build(2*x+1,mid+1,r);end;procedure pushdown(x:longint);begin   if t[x].flag then   begin      t[x].flag:=false;      t[2*x].flag:=not t[2*x].flag;      t[2*x].sum:=t[2*x].r-t[2*x].l+1-t[2*x].sum;      t[2*x+1].flag:=not t[2*x+1].flag;      t[2*x+1].sum:=t[2*x+1].r-t[2*x+1].l+1-t[2*x+1].sum;   end;end;procedure change(x,l,r:longint);var        mid:longint;begin   if (t[x].l=l) and (t[x].r=r) then   begin      t[x].flag:=not t[x].flag;      t[x].sum:=t[x].r-t[x].l+1-t[x].sum;      exit;   end;   pushdown(x);   mid:=(t[x].l+t[x].r)>>1;   if (r<=mid) then change(2*x,l,r) else     if (l>mid) then change(2*x+1,l,r) else      begin         change(2*x,l,mid);         change(2*x+1,mid+1,r);      end;   t[x].sum:=t[2*x].sum+t[2*x+1].sum;end;function get_sum(x,l,r:longint):longint;var        mid:longint;begin   if (t[x].l=l) and (t[x].r=r) then exit(t[x].sum);   pushdown(x);   mid:=(t[x].l+t[x].r)>>1;   if r<=mid then exit(get_sum(2*x,l,r)) else     if l>mid then exit(get_sum(2*x+1,l,r)) else       exit(get_sum(2*x,l,mid)+get_sum(2*x+1,mid+1,r));end;begin   read(n,m);   build(1,1,n);   for i:=1 to m do   begin      read(op,x,y);      if op=0 then change(1,x,y)        else writeln(get_sum(1,x,y));   end;end.
——by Eirlys



0 0
原创粉丝点击