JZOJ 4.8 2435——校门外的树【树状数组】

Description

校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的……
如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现有两个操作:
K=1,读入l,r表示在l~r之间种上的一种树
K=2,读入l,r表示询问l~r之间能见到多少种树
(l,r>0)

Input

第一行n,m表示道路总长为n,共有m个操作
接下来m行为m个操作

Output

对于每个k=2输出一个答案

Sample Input

5 4
1 1 3
2 2 5
1 2 4
2 3 5
Sample Output

1
2
Hint

范围:20%的数据保证,n,m<=100
60%的数据保证,n <=1000,m<=50000
100%的数据保证,n,m<=50000


其实可以理解为括号序列,L为“(“,R为”)”
其实就是在这个区间找到多少个左括号,和右括号
假设这时候需要统计的是 5 10之间有多少种树,那么,只要在10之前种的树都是有效的(这时候先不管5的限制),也就是统计左括号的个数,一共是6个,下面加上5个限制,也就是说,在5之前,我们统计一下有多少右括号,也就是能与左括号匹配掉的括号有多少个?换句话说,就是有多少种树被限制了。
所以就是将findl(r)-findr(l-1)求出来


代码如下:

var s1,s2:array[0..50000]of longint;
    n,m:longint;

function lowbit(x:longint):longint;
begin
        lowbit:=x and (x xor (x-1));
end;

procedure addl(i:longint);
begin
        while i<=n do
                begin
                        inc(s1[i]);
                        inc(i,lowbit(i));
                end;
end;

procedure addr(i:longint);
begin
        while i<=n do
                begin
                        inc(s2[i]);
                        inc(i,lowbit(i));
                end;
end;

function findl(i:longint):longint;
begin
        findl:=0;
        while i>0 do
                begin
                        inc(findl,s1[i]);
                        dec(i,lowbit(i));
                end;
end;

function findr(i:longint):longint;
begin
        findr:=0;
        while i>0 do
                begin
                        inc(findr,s2[i]);
                        dec(i,lowbit(i));
                end;
end;

procedure main;
var i,j,d,k,r,l:longint;
begin
        readln(n,m);
        for i:=1 to m do
                begin
                        readln(k,l,r);
                        if k=1 then
                                begin
                                        addl(l);
                                        addr(r);
                                end
                        else
                                begin
                                        write(findl(r)-findr(l-1));
                                        writeln;
                                end;
                end;
end;

begin
        main;
end.
原文地址:https://www.cnblogs.com/Comfortable/p/8412324.html