您的位置:首页 > 其它

bzoj1690开关灯

2015-06-04 18:04 330 查看
线段树模版

1690 开关灯

program hehe;
type
tree=record
l,r,h,s:longint;
end;
var
n,m,i,j,k,f:longint;
x:array[0..1000000] of tree;

procedure build(a,l,r:longint);
var
mid:longint;
begin
x[a].l:=l;
x[a].r:=r;
x[a].h:=0;
x[a].s:=0;
if l=r then exit;
mid:=(l+r)>>1;
build(a<<1,l,mid);
build(a<<1+1,mid+1,r);
end;

procedure down(a:longint);
begin
if x[a].s<>0 then
begin
x[a<<1].s:=(x[a<<1].s+1)and 1;
x[a<<1+1].s:=(x[a<<1+1].s+1)and 1;
x[a<<1].h:=x[a<<1].r-x[a<<1].l-x[a<<1].h+1;
x[a<<1+1].h:=x[a<<1+1].r-x[a<<1+1].l-x[a<<1+1].h+1;
x[a].s:=0;
end;
end;

procedure gai(a,l,r:longint);
var
mid:longint;
begin
down(a);
if (x[a].l=l)and(x[a].r=r) then
begin
x[a].s:=1;
x[a].h:=x[a].r-x[a].l-x[a].h+1;
end
else
begin
mid:=(x[a].l+x[a].r)>>1;
if r<=mid then gai(a<<1,l,r)
else if l>mid then gai(a<<1+1,l,r)
else
begin
gai(a<<1,l,mid);
gai(a<<1+1,mid+1,r);
end;
x[a].h:=x[a<<1].h+x[a<<1+1].h;
end;
end;

function find(a,l,r:longint):longint;
var
mid:longint;
begin
down(a);
if (x[a].l=l)and(x[a].r=r) then exit(x[a].h);
mid:=(x[a].l+x[a].r)>>1;
if r<=mid then exit(find(a<<1,l,r));
if l>mid then exit(find(a<<1+1,l,r));
exit(find(a<<1,l,mid)+find(a<<1+1,mid+1,r));
end;

begin
readln(n,m);
build(1,1,n);
for i:=1 to m do
begin
readln(j,k,f);
if j=0 then gai(1,k,f)
else writeln(find(1,k,f));
end;
end.


View Code

USACO

时间限制: 1 s

空间限制: 128000 KB

题目等级 : 钻石 Diamond

题解

题目描述 Description

YYX家门前的街上有N(2<=N<=100000)盏路灯,在晚上六点之前,这些路灯全是关着的,六点之后,会有M(2<=m<=100000)个人陆续按下开关,这些开关可以改变从第i盏灯到第j盏灯的状态,现在YYX想知道,从第x盏灯到第y盏灯中有多少是亮着的(1<=i,j,x,y<=N)

输入描述 Input Description

第 1 行: 用空格隔开的两个整数N和M
第 2..M+1 行: 每行表示一个操作, 有三个用空格分开的整数: 指令号(0代表按下开关,1代表询问状态), x 和 y

输出描述 Output Description

第 1..询问总次数 行:对于每一次询问,输出询问的结果

样例输入 Sample Input

4 5
0 1 2
0 2 4
1 2 3
0 2 4
1 1 4

样例输出 Sample Output

1
2

数据范围及提示 Data Size & Hint

一共4盏灯,5个操作,下面是每次操作的状态(X代表关上的,O代表开着的):

XXXX -> OOXX -> OXOO -> 询问1~3 -> OOXX -> 询问1~4
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: