bzoj1690开关灯

线段树模版

1690 开关灯

 
 1 program hehe;
 2 type
 3  tree=record
 4   l,r,h,s:longint;
 5  end;
 6 var
 7  n,m,i,j,k,f:longint;
 8  x:array[0..1000000] of tree;
 9 
10   procedure build(a,l,r:longint);
11   var
12    mid:longint;
13   begin
14    x[a].l:=l;
15    x[a].r:=r;
16    x[a].h:=0;
17    x[a].s:=0;
18    if l=r then exit;
19    mid:=(l+r)>>1;
20    build(a<<1,l,mid);
21    build(a<<1+1,mid+1,r);
22   end;
23 
24   procedure down(a:longint);
25   begin
26    if x[a].s<>0 then
27    begin
28     x[a<<1].s:=(x[a<<1].s+1)and 1;
29     x[a<<1+1].s:=(x[a<<1+1].s+1)and 1;
30     x[a<<1].h:=x[a<<1].r-x[a<<1].l-x[a<<1].h+1;
31     x[a<<1+1].h:=x[a<<1+1].r-x[a<<1+1].l-x[a<<1+1].h+1;
32     x[a].s:=0;
33    end;
34   end;
35 
36   procedure gai(a,l,r:longint);
37   var
38    mid:longint;
39   begin
40    down(a);
41    if (x[a].l=l)and(x[a].r=r) then
42    begin
43     x[a].s:=1;
44     x[a].h:=x[a].r-x[a].l-x[a].h+1;
45    end
46    else
47    begin
48     mid:=(x[a].l+x[a].r)>>1;
49     if r<=mid then gai(a<<1,l,r)
50     else if l>mid then gai(a<<1+1,l,r)
51     else
52     begin
53      gai(a<<1,l,mid);
54      gai(a<<1+1,mid+1,r);
55     end;
56     x[a].h:=x[a<<1].h+x[a<<1+1].h;
57    end;
58   end;
59 
60   function find(a,l,r:longint):longint;
61   var
62    mid:longint;
63   begin
64    down(a);
65    if (x[a].l=l)and(x[a].r=r) then exit(x[a].h);
66    mid:=(x[a].l+x[a].r)>>1;
67    if r<=mid then exit(find(a<<1,l,r));
68    if l>mid then exit(find(a<<1+1,l,r));
69    exit(find(a<<1,l,mid)+find(a<<1+1,mid+1,r));
70   end;
71 
72 begin
73  readln(n,m);
74  build(1,1,n);
75  for i:=1 to m do
76  begin
77   readln(j,k,f);
78   if j=0 then gai(1,k,f)
79   else writeln(find(1,k,f));
80  end;
81 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

posted @ 2015-06-04 18:04  ChenThree  阅读(164)  评论(0编辑  收藏  举报