bzoj 1230 线段树 标签

61 篇文章 0 订阅
7 篇文章 0 订阅

题意: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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值