zoukankan      html  css  js  c++  java
  • POJ 3468

    POJ 3468

    题目之前的吐槽:最近记忆力真的差很多了,刚刚做完来写解题报告,题目编号已然不记得….

    题目大意:给出n个数,我们有两个操作,q,x,y:询问区间[x,y]的和,c,x,y,z:区间[x,y]里的每一个数+z。

    解:树状数组,线段树,以及discuss里说splay可做。做这题目前用的线段树。线段树的常数真心恶心,递归就算了,而且clear操作写成函数那个常数大得我不敢看了,可是不写成函数又会把自己恶心到。

    主要是靠一个lazy操作,有一个tag域,如果这个区间在增加的区间内,tag累加,tag表示这个区间要加的数,然后每进入一条线段,clear,更新sum,tag直0,并且把tag传递给子节点(线段)(因为自线段的sum域没有更新)。本体wa点也是很多,首先每看清题目,数据范围超过maxlongint,然后也没想到增加的数可能为负,然后我写的条件是tag>0 then…,然后在累加数的时候,从子节点返回时,需要clear一次,然后 sum := _sum(sons.sum),累加的时候退出不用clear了,进入的时候clear就行(毕竟不像_addnum,他是改变了值的了),然后自己的函数命名的习惯还是改不太过来…

    线段树
      1 //poj 3468
    2 const
    3 inf='1.txt';
    4 maxn=111111;
    5 type
    6 data=record
    7 mid, l, r, st, ed: longint;
    8 sum, tag: int64;
    9 end;
    10 var
    11 tree: array[0..maxn*4]of data;
    12 a: array[0..maxn]of int64;
    13 n, q: longint;
    14 ans: int64;
    15 procedure _clear(k: longint);
    16 begin
    17 with tree[k] do if tag <> 0 then begin
    18 sum := sum + tag*(ed-st+1);
    19 if (st<>ed) then begin
    20 tree[l].tag := tree[l].tag + tag;
    21 tree[r].tag := tree[r].tag + tag;
    22 end;
    23 tag := 0;
    24 end;
    25 end;
    26
    27 procedure _build(s, e, k: longint);
    28 begin
    29 with tree[k] do begin
    30 st := s; ed := e; mid := (st+ed)>>1;
    31 if s=e then begin
    32 sum := a[s]; exit;
    33 end;
    34 l := k << 1; _build(s, mid, l);
    35 r := l + 1; _build(mid+1, e, r);
    36 sum := tree[l].sum + tree[r].sum;
    37 end;
    38 end;
    39
    40 procedure _init;
    41 var
    42 i: longint;
    43 begin
    44 fillchar(tree, sizeof(tree), 0);
    45 readln(n, q);
    46 for i := 1 to n do read(a[i]);
    47 readln;
    48 _build(1, n, 1);
    49 end;
    50
    51 procedure _count(s, e, k: longint);
    52 begin
    53 with tree[k] do begin
    54 _clear(k);
    55 if (s<=st)and(ed<=e) then begin
    56 ans := ans + sum; exit;
    57 end;
    58 if s<=mid then _count(s, e, l);
    59 if e>mid then _count(s, e, r);
    60 if (l>0) then _clear(l);
    61 if (r>0) then _clear(r);
    62 end;
    63 end;
    64
    65 procedure _addnum(s, e, k: longint; num: int64);
    66 begin
    67 with tree[k] do begin
    68 _clear(k);
    69 if (s<=st)and(ed<=e) then begin
    70 tag := tag + num; exit;
    71 end;
    72 if s<=mid then _addnum(s, e, l, num);
    73 if e>mid then _addnum(s, e, r, num);
    74 if (l>0) then _clear(l);
    75 if (r>0) then _clear(r);
    76 sum := tree[l].sum + tree[r].sum;
    77 end;
    78 end;
    79
    80 procedure _main;
    81 var
    82 i, x, y, z: longint;
    83 c: char;
    84 begin
    85 for i := 1 to q do begin
    86 read(c);
    87 if c='Q' then begin
    88 readln(x, y);
    89 ans := 0;
    90 _count(x, y, 1);
    91 writeln(ans);
    92 end
    93 else begin
    94 readln(x, y, z);
    95 _addnum(x, y, 1, z);
    96 end;
    97 end;
    98 end;
    99
    100 begin
    101 assign(input,inf); reset(input);
    102 _init;
    103 _main;
    104 end.


    新增加一个splay版本

    View Code
      1 //orzorzorz
      2 const
      3         maxn=100011;
      4         inf='1.txt';
      5         null=maxn;
      6 type
      7         node=record
      8           tag, key, sum: int64; {sb= =}
      9           father, size: longint;
     10           son: array[0..1]of longint;
     11         end;
     12 var
     13         tree: array[0..maxn]of node;
     14         root, n, q, tot: longint;
     15 procedure clear(x: longint);
     16 begin
     17   if (tree[x].tag<>0)and(x<>null) then
     18   with tree[x] do begin
     19     key := key + tag;
     20     inc(tree[son[0]].tag, tag);
     21     inc(tree[son[1]].tag, tag);
     22     tree[son[0]].sum := tree[son[0]].sum + tag * tree[son[0]].size;
     23     tree[son[1]].sum := tree[son[1]].sum + tag * tree[son[1]].size;
     24     tag := 0;
     25   end;
     26 end;
     27 
     28 procedure updata(x: longint);
     29 begin
     30   with tree[x] do begin
     31     sum := tree[son[0]].sum + key + tree[son[1]].sum;
     32     size := tree[son[0]].size + 1 + tree[son[1]].size;
     33   end;
     34 end;
     35 
     36 function find(x: longint): longint;
     37 var
     38         i : longint;
     39 begin
     40   i := root;
     41   while true do with tree[i] do begin
     42     clear(x);
     43     if tree[son[0]].size + 1 = x then exit(i);
     44     if tree[son[0]].size + 1 > x then i := son[0]
     45     else begin
     46       x := x - tree[son[0]].size - 1;
     47       i := son[1];
     48     end;
     49   end;
     50 end;
     51 
     52 procedure rotate(x: longint);
     53 var
     54         isr, y, z: longint;
     55 begin
     56   with tree[x] do begin
     57     y := father; if y=root then root := x;
     58     if tree[y].son[1] = x then isr := 1 else isr := 0;
     59     {clear son}    //clear(tree[y].son[0]); clear(tree[y].son[1]); clear(son[0]); clear(son[1]);
     60     clear(y); clear(x);
     61     tree[y].son[isr] := son[isr xor 1];
     62     if son[isr xor 1]<>null then tree[son[isr xor 1]].father := y;
     63     z := tree[y].father; father := z;
     64     if z<>null then begin
     65       if y=tree[z].son[0] then tree[z].son[0] := x
     66         else tree[z].son[1] := x;
     67     end;
     68     tree[y].father := x;
     69     tree[x].son[isr xor 1] := y;
     70   end;
     71   updata(y);
     72 end;
     73 
     74 procedure splay(x, goal: longint);
     75 var
     76         u, v, y, z: longint;
     77 begin
     78   while tree[x].father<>goal do with tree[x] do begin
     79     y := father; if tree[y].father=goal then begin
     80       rotate(x); continue;
     81     end;
     82     z := tree[y].father;
     83     if tree[y].son[0]=x then u := 0 else u := 1;
     84     if tree[z].son[0]=y then v := 0 else v := 1;
     85     if (u xor v=0) then begin
     86       rotate(y); rotate(x);
     87     end
     88     else begin
     89       rotate(x); rotate(x);
     90     end;
     91   end;
     92   updata(x);
     93 end;
     94 
     95 procedure change(x, y, number: longint);
     96 var
     97         l, r : longint;
     98 begin
     99   l := find(x-1);
    100   splay(l, null);
    101   r := find(y+1);
    102   splay(r, root);
    103   r := tree[r].son[0];
    104   with tree[r] do begin
    105     inc(tag, number);
    106     clear(r);
    107   end;
    108   updata(r);
    109   updata(tree[root].son[1]);
    110   updata(root);
    111 end;
    112 
    113 function query(x, y: longint): int64;
    114 var
    115         l, r: longint;
    116 begin
    117   l := find(x-1);
    118   splay(l, null);
    119   r := find(y+1);
    120   splay(r, root);
    121   r := tree[r].son[0];
    122   query := tree[r].sum;
    123 end;
    124 
    125 
    126 procedure main;
    127 var
    128         i, a, b, c: longint;
    129         ask: char;
    130 begin
    131   for i := 1 to q do begin
    132     read(ask);
    133     if ask='Q' then begin
    134       readln(a, b); inc(a); inc(b);
    135       writeln(query(a, b));
    136     end
    137     else begin
    138       readln(a, b, c); inc(a); inc(b);
    139       change(a, b, c);
    140     end;
    141   end;
    142 end;
    143 
    144 procedure init;
    145 var
    146         i: longint;
    147 begin
    148   readln(n, q);
    149   fillchar(tree[null], sizeof(tree[null]), 0);
    150   fillchar(tree[0], sizeof(tree[0]), 0);
    151   with tree[0] do begin
    152     size := 1; son[0] := null; son[1] := null; father := 1;
    153   end;
    154   fillchar(tree[n+1], sizeof(tree[n+1]), 0);
    155   with tree[(n+1)] do begin
    156     size := 1; son[0] := null; son[1] := null; father := n;
    157   end;
    158   for i := 1 to n do with tree[i] do begin
    159     son[0] := i-1; son[1] := null; father := i+1; tag := 0;
    160     if i=n then son[1] := n+1;
    161     read(key);
    162     updata(i);
    163   end; readln;
    164   root := n;
    165   tree[root].father := null;
    166 end;
    167 
    168 begin
    169   assign(input,inf); reset(input);   assign(output,'2.txt'); rewrite(output);
    170   init;
    171   main;
    172 end.



  • 相关阅读:
    C puzzles详解【51-57题】
    C puzzles详解【46-50题】
    C puzzles详解【38-45题】
    C puzzles详解【34-37题】
    C puzzles详解【31-33题】
    C puzzles详解【26-30题】
    C puzzles详解【21-25题】
    C puzzles详解【16-20题】
    使用C++模板实现栈的求最小值功能
    模拟求幂运算,考虑的已经很周全了
  • 原文地址:https://www.cnblogs.com/wmzisfoolish/p/2435219.html
Copyright © 2011-2022 走看看