宋壬初吧 关注:25贴子:419

回复:线段树套SBT。。

只看楼主收藏回复

            else max := mid;
        end;
        writeln ( max );
    end;
   
procedure dealS;
    var
        l , r , p , d : longint;
        s : char;
    begin
        read ( s );
        if s = 'Q' then begin
            readln ( l , r , d );
            queryL ( l , r , d );
        end
        else begin
            readln ( p , d );
            modifyL ( p , d );
        end;
    end;
   
procedure main;
    var
        i : longint;
    begin
        readln ( n , m );
        totmin := maxlongint;
        totmax := 0;
        w := 0;
        h := 0;
        while 1 shl h < n do inc ( h );
        buildL;
        for i := 1 to n do begin
            read ( data[i] );
            if data[i] < totmin then
                totmin := data[i];
            if data[i] > totmax then
                totmax := data[i];
            insertL ( i );
        end; readln;
        for i := 1 to m do
            dealS;
    end;
   
begin
    readln ( x );
    for c := 1 to x do
        main;
end.


17楼2011-02-14 16:20
回复
    zoj2112
    追随前人的脚步……


    18楼2011-02-14 16:20
    回复
      用C/C++的话应该会更好看一点。


      IP属地:上海19楼2011-02-17 14:13
      回复
        写class?


        20楼2011-02-18 18:58
        回复
                  else
                      if tree[tree[tree[p].le].le].size > tree[tree[p].ri].size then
                          rightrotateT ( p )
                      else
                          if tree[tree[tree[p].le].ri].size > tree[tree[p].ri].size then begin
                              leftrotateT ( tree[p].le );
                              rightrotateT ( p );
                          end
                          else exit;
                  maintainT ( tree[p].le , false );
                  maintainT ( tree[p].ri , true );
                  maintainT ( p , true );
                  maintainT ( p , false );
              end;
             
          procedure insertT ( var p : longint; v : longint );
              begin
                  if p = 0 then begin
                      p := w; inc ( w );
                      newT(p); tree[p].data := v;
                  end
                  else begin
                      inc ( tree[p].size );
                      if tree[p].data < v then
                          insertT ( tree[p].ri , v )
                      else
                          insertT ( tree[p].le , v );
                      maintainT ( p , tree[p].data < v );
                  end;
              end;
             
          function deleteT ( var p : longint; v : longint ): longint;
              begin
                  dec ( tree[p].size );
                  if (tree[p].data=v) or (tree[p].data<v) and (tree[p].ri=0) then begin
                      deleteT := tree[p].data;
                      if (tree[p].le=0) or (tree[p].ri=0) then begin
                          w := p; p := tree[p].le+tree[p].ri;
                      end
                      else tree[p].data := deleteT ( tree[p].le , maxlongint );
          


          22楼2011-02-24 09:48
          回复
                    end
                    else
                        if tree[p].data < v then
                            deleteT := deleteT ( tree[p].ri , v )
                        else
                            deleteT := deleteT ( tree[p].le , v );
                end;
               
            function findT ( p , v : longint ): longint;
                begin
                    if p = 0 then exit ( 0 );
                    if tree[p].data <= v then
                        findT := tree[tree[p].le].size + 1 + findT ( tree[p].ri , v )
                    else findT := findT ( tree[p].le , v );
                end;
               
            procedure insertL ( d : longint );
                var
                    p : longint;
                begin
                    p := data[d]+s;
                    while p<> 1 do begin
                        insertT ( line[p] , d );
                        p := p shr 1;
                    end;
                end;
               
            procedure modifyL ( d , v : longint );
                var
                    p , q : longint;
                begin
                    p := data[d]+s; q := v+s;
                    while p<>q do begin
                        deleteT ( line[p] , d );
                        insertT ( line[q] , d );
                        p := p shr 1;
                        q := q shr 1;
                    end; data[d] := v;
                end;
               
            function findL ( p , l , r : longint ): longint;
                begin
                    findL := findT ( line[p] , r ) - findT ( line[p] , l-1 );
                end;
               
            procedure queryL ( l , r , k : longint );
                var
                    p , d : longint;
                begin
                    p := 1;
                    while p<= s do begin
                        d := findL ( p shl 1 , l , r );
                        if d < k then begin
                            dec ( k , d );
            


            23楼2011-02-24 09:48
            回复
                              p := p shl 1 xor 1;
                          end
                          else p := p shl 1;
                      end;
                      writeln ( rank[p-s] );
                  end;
                 
              procedure buildL;
                  var
                      b : longint;
                  begin
                      b := 1;
                      while b < s do b := b shl 1;
                      s := b;
                      fillchar ( line , s shl 3 , 0 );
                      dec ( s );
                  end;
                 
              procedure Isort ( l , r : longint );
                  var
                      i , j , k : longint;
                  begin
                      for i := l+1 to r do begin   
                          j := i; k := link[i];
                          while (j>l) and (tmp[link[j-1]]>tmp[k]) do begin
                              link[j] := link[j-1]; dec ( j );
                          end; link[j] := k;
                      end;
                  end;
                 
              procedure Qsort ( l , r : longint );
                  var
                      i , j , k , d : longint;
                  begin
                      if r-l <= 16 then begin
                          Isort ( l , r ); exit;
                      end;
                      i := l; j := r;
                      k := tmp[link[(l+r)shr 1]];
                      repeat
                          while tmp[link[i]] < k do inc ( i );
                          while tmp[link[j]] > k do dec ( j );
                          if i <= j then begin
                              d := link[i]; link[i] := link[j]; link[j] := d;
                              inc ( i ); dec ( j );
                          end;
                      until i>j;
                      Qsort ( i , r ); Qsort ( l , j );
                  end;
                 
              procedure discrete;
                  var
                      i , k , v : longint;
              


              24楼2011-02-24 09:48
              回复
                    begin
                        for i := 1 to s do
                            link[i] := i;
                        Qsort ( 1 , s );
                        k := 0; v := -1;
                        for i := 1 to s do begin
                            if tmp[link[i]] > v then begin
                                inc ( k ); v := tmp[link[i]];
                                rank[k] := v;
                            end; tmp[link[i]] := k;
                        end;
                        s := k;
                    end;
                   
                procedure main;
                    var
                        i : longint;
                        ch : char;
                    begin
                        readln ( n , m );
                        s := 0; w := 1;
                        for i := 1 to n do begin
                            inc ( s ); read ( tmp[s] );
                            data[i] := s;
                        end; readln;
                        for i := 1 to m do begin
                            read ( ch );
                            if ch = 'C' then begin
                                inc ( s ); rec[i,0] := 0;
                                readln ( rec[i,1] , tmp[s] );
                                rec[i,2] := s;
                            end
                            else readln ( rec[i,1] , rec[i,2] , rec[i,0] );
                        end;
                        discrete; buildL;
                        for i := 1 to n do begin
                            data[i] := tmp[data[i]];
                            insertL ( i );
                        end;
                        for i := 1 to m do begin
                            if rec[i,0] = 0 then begin
                                rec[i,2] := tmp[rec[i,2]];
                                modifyL ( rec[i,1] , rec[i,2] );
                            end
                            else queryL ( rec[i,1] , rec[i,2] , rec[i,0] );
                        end;
                    end;
                   
                begin
                    readln ( x );
                    for t := 1 to x do
                        main;
                end.
                


                25楼2011-02-24 09:48
                回复