Differences From Artifact [f9b609a5f0b95ebf]:
- File        
lib/dataStructure/segmentTree.cpp
- 2012-06-07 14:24:24 - part of checkin [34dd53bac9] on branch trunk - TCO12-2C (user: kinaba) [annotate]
 
 
To Artifact [b7ca5af5f1eab32a]:
- File        
lib/dataStructure/segmentTree.cpp
- 2013-09-14 20:29:31 - part of checkin [94afd8e13c] on branch trunk - Segment tree with range update. (user: kinaba) [annotate]
 
 
    1  //-------------------------------------------------------------                        1  //-------------------------------------------------------------
    2  // Segment tree                                                                        2  // Segment tree
    3  //   in some general form                                                              3  //   in some general form
    4  //                                                                                     4  //
    5  // Verified by                                                                         5  // Verified by
    6  //   - Codeforces 107 C                                                          |     6  //   - Codeforces 200 D
                                                                                        >     7  //   - Codeforces 107 C (old version)
    7  //   - Codeforces 104 E                                                          |     8  //   - Codeforces 104 E (old version)
    8  //-------------------------------------------------------------                        9  //-------------------------------------------------------------
    9                                                                                        10  
   10  template<typename Node>                                                          <
   11  class SegmentTree                                                                     11  class SegmentTree
   12  {                                                                                     12  {
                                                                                        >    13          struct Node
                                                                                        >    14          {
                                                                                        >    15                  int sum;
                                                                                        >    16  
                                                                                        >    17                  static Node Zero()
                                                                                        >    18                  {
                                                                                        >    19                          Node c = {0};
                                                                                        >    20                          return c;
                                                                                        >    21                  }
                                                                                        >    22                  static Node One(int v)
                                                                                        >    23                  {
                                                                                        >    24                          Node c = {v};
                                                                                        >    25                          return c;
                                                                                        >    26                  }
                                                                                        >    27                  static Node Concat(const Node& l, const Node& r)
                                                                                        >    28                  {
                                                                                        >    29                          Node c = {l.sum + r.sum};
                                                                                        >    30                          return c;
                                                                                        >    31                  }
                                                                                        >    32                  static Node Repeat(const Node& n, int k)
                                                                                        >    33                  {
                                                                                        >    34                          if(k==0) return Zero();
                                                                                        >    35                          Node c = {n.sum * k};
                                                                                        >    36                          return c;
                                                                                        >    37                  }
                                                                                        >    38  
                                                                                        >    39                  bool lazy;
                                                                                        >    40          };
                                                                                        >    41  
   13  public:                                                                               42  public:
   14          template<typename Seq>                                                        43          template<typename Seq>
   15          SegmentTree(const Seq& s) {                                                   44          SegmentTree(const Seq& s) {
   16                  int N = 1;                                                            45                  int N = 1;
   17                  while( N < s.size() )                                                 46                  while( N < s.size() )
   18                          N <<= 1;                                                      47                          N <<= 1;
   19                                                                                        48  
................................................................................................................................................................................
   29          }                                                                             58          }
   30                                                                                        59  
   31          Node Query(int s, int e) { // compute h( seq[s,e) ) :  O(log n)               60          Node Query(int s, int e) { // compute h( seq[s,e) ) :  O(log n)
   32                  return QueryRec(s, e, tree.size()-1, 0, tree[0].size());              61                  return QueryRec(s, e, tree.size()-1, 0, tree[0].size());
   33          }                                                                             62          }
   34                                                                                        63  
   35          template<typename Value>                                                      64          template<typename Value>
   36          void Set(int s, int e, Value v) { // seq[s,e):=v : O(log n |e-s|)        |    65          void Set(int s, int e, Value v) { // seq[s,e):=v : O(log n)
   37                  SetRec(s, e, Node::One(v), tree.size()-1, 0, tree[0].size());         66                  SetRec(s, e, Node::One(v), tree.size()-1, 0, tree[0].size());
   38          }                                                                             67          }
   39                                                                                        68  
   40  private:                                                                              69  private:
   41          void CalcMidNode(int lv, int idx)                                        <
   42          {                                                                        <
   43                  tree[lv][idx] = Node::Concat(tree[lv-1][idx*2], tree[lv-1][idx*2 <
   44          }                                                                        <
   45                                                                                   <
   46          Node QueryRec(int s, int e, int lv, int idx, int stride)                      70          Node QueryRec(int s, int e, int lv, int idx, int stride)
   47          {                                                                             71          {
   48                  const int myL = stride*idx;                                           72                  const int myL = stride*idx;
   49                  const int myR = stride*(idx+1);                                       73                  const int myR = stride*(idx+1);
   50                  if( e<=myL || myR<=s )                                                74                  if( e<=myL || myR<=s )
   51                          return Node::Zero();                                          75                          return Node::Zero();
                                                                                        >    76                  ResolveLazy(lv, idx);
                                                                                        >    77  
   52                  if( s<=myL && myR<=e )                                                78                  if( s<=myL && myR<=e )
   53                          return tree[lv][idx];                                         79                          return tree[lv][idx];
   54                  return Node::Concat(QueryRec(s,e,lv-1,idx*2,stride/2),                80                  return Node::Concat(QueryRec(s,e,lv-1,idx*2,stride/2),
   55                                      QueryRec(s,e,lv-1,idx*2+1,stride/2));             81                                      QueryRec(s,e,lv-1,idx*2+1,stride/2));
   56          }                                                                             82          }
   57                                                                                        83  
   58          void SetRec(int s, int e, const Node& n, int lv, int idx, int stride)         84          void SetRec(int s, int e, const Node& n, int lv, int idx, int stride)
   59          {                                                                             85          {
   60                  const int myL = stride*idx;                                           86                  const int myL = stride*idx;
   61                  const int myR = stride*(idx+1);                                       87                  const int myR = stride*(idx+1);
   62                  if( e<=myL || myR<=s )                                                88                  if( e<=myL || myR<=s )
   63                          return;                                                       89                          return;
                                                                                        >    90                  ResolveLazy(lv, idx);
                                                                                        >    91  
   64                  if( stride == 1 ) {                                                   92                  if( stride == 1 ) {
   65                          tree[lv][idx] = n;                                            93                          tree[lv][idx] = n;
   66                  } else {                                                              94                  } else {
                                                                                        >    95                          if( s<=myL && myR<=e ) {
                                                                                        >    96                                  tree[lv][idx] = n;
                                                                                        >    97                                  tree[lv][idx].lazy = true;
                                                                                        >    98                                  ResolveLazy(lv, idx);
                                                                                        >    99                                  return;
                                                                                        >   100                          }
   67                          SetRec(s,e,n,lv-1,idx*2,stride/2);                           101                          SetRec(s,e,n,lv-1,idx*2,stride/2);
   68                          SetRec(s,e,n,lv-1,idx*2+1,stride/2);                         102                          SetRec(s,e,n,lv-1,idx*2+1,stride/2);
   69                          CalcMidNode(lv, idx);                                        103                          CalcMidNode(lv, idx);
   70                  }                                                                    104                  }
   71          }                                                                            105          }
   72                                                                                       106  
   73          vector< vector<Node> > tree;                                             |   107          void CalcMidNode(int lv, int idx)
   74  };                                                                               <
                                                                                        >   108          {
                                                                                        >   109                  tree[lv][idx] = Node::Concat(tree[lv-1][idx*2], tree[lv-1][idx*2
                                                                                        >   110          }
   75                                                                                       111  
   76  struct Node                                                                      |   112          void ResolveLazy(int lv, int idx)
   77  {                                                                                <
   78          double sum;                                                              <
   79          double maxLeft;                                                          <
   80          double maxRight;                                                         <
   81          double maxSum;                                                           <
   82          static Node Zero()                                                       <
   83          {                                                                            113          {
   84                  Node c = {0, 0, 0, 0};                                           |   114                  if(tree[lv][idx].lazy) {
   85                  return c;                                                        |   115                          if(lv > 0) {
   86          }                                                                        <
   87          static Node One(double v)                                                <
   88          {                                                                        <
   89                  Node c = {v, max(0.0,v), max(0.0,v), max(0.0,v)};                <
   90                  return c;                                                        <
   91          }                                                                        <
   92          static Node Concat(const Node& l, const Node& r)                         <
   93          {                                                                        <
   94                  Node c = {                                                       <
   95                          l.sum + r.sum,                                           <
   96                          max(l.maxLeft, l.sum+r.maxLeft),                         <
   97                          max(l.maxRight+r.sum, r.maxRight),                       <
   98                          max(max(l.maxSum, r.maxSum), l.maxRight+r.maxLeft),      <
   99                  };                                                               <
  100                  return c;                                                        <
  101          }                                                                        <
  102  };                                                                               <
  103                                                                                   <
  104  /*                                                                               <
  105  class SegmentTree                                                                <
  106  {                                                                                <
  107          // --- DATA FOR EACH NODE ---                                            <
  108          struct Node                                                              <
  109          {                                                                        <
  110                  int sum;                                                         <
  111                  int maxLeft;                                                     <
  112                  int minLeft;                                                     <
  113                  int n4;                                                          <
  114                  int n7;                                                          <
  115                  bool switched;                                                   <
  116          };                                                                       <
  117          // --- DATA FOR EACH NODE ---                                            <
  118                                                                                   <
  119          Node Canonical(int lv, int idx)                                          <
  120          {                                                                        <
  121                  Node& x = tree[lv][idx];                                         |   116                                  tree[lv-1][idx*2]   = tree[lv][idx];
  122                  // --- DO SOMETHING IF YOU NEED CANONICALIZATION ---             <
  123                  if( !x.switched )                                                <
  124                          return x;                                                <
  125                  Node n = {-x.sum, -x.minLeft, -x.maxLeft, x.n7, x.n4, false};    <
  126                  return n;                                                        <
  127                  // --- DO SOMETHING IF YOU NEED CANONICALIZATION ---             <
                                                                                        >   117                                  tree[lv-1][idx*2+1] = tree[lv][idx];
  128          }                                                                        |   118                          }
                                                                                        >   119                          tree[lv][idx] = Node::Repeat(tree[lv][idx], 1<<lv);
  129                                                                                   |   120                  }
  130          void UpdateMidNode(int lv, int idx)                                      <
  131          {                                                                        <
  132                  Node l = Canonical(lv-1, idx*2);                                 <
  133                  Node r = Canonical(lv-1, idx*2+1);                               <
  134                  // --- BOTTOM UP COMPUTATION ---                                 <
  135                  Node me = {                                                      <
  136                          l.sum + r.sum,                                           <
  137                          max(l.maxLeft, l.sum+r.maxLeft),                         <
  138                          min(l.minLeft, l.sum+r.minLeft),                         <
  139                          l.n4 + r.n4,                                             <
  140                          l.n7 + r.n7,                                             <
  141                          false                                                    <
  142                  };                                                               <
  143                  // --- BOTTOM UP COMPUTATION ---                                 <
  144                  tree[lv][idx] = me;                                              <
  145          }                                                                            121          }
  146                                                                                       122  
  147          vector< vector<Node> > tree;                                                 123          vector< vector<Node> > tree;
  148                                                                                   <
  149  public:                                                                          <
  150          SegmentTree(const string& s)                                             <
  151          {                                                                        <
  152                  int N = 1;                                                       <
  153                  while( N < s.size() )                                            <
  154                          N <<= 1;                                                 <
  155                                                                                   <
  156                  tree.resize(tree.size()+1); tree.back().resize(N);               <
  157                  for(int i=0; i<N; ++i)                                           <
  158                  {                                                                <
  159                          // --- INITIALIZE BASE 1-ELEMENT NODES ---               <
  160                          int v = i<s.size() ? (s[i]=='4' ? +1 : -1) : 0;          <
  161                          Node me = {v, max(0,v), min(0,v), v==+1, v==-1, false};  <
  162                          // --- INITIALIZE BASE 1-ELEMENT NODES ---               <
  163                          tree.back()[i] = me;                                     <
  164                  }                                                                <
  165                                                                                   <
  166                  while(N>>=1)                                                     <
  167                  {                                                                <
  168                          tree.resize(tree.size()+1); tree.back().resize(N);       <
  169                          for(int i=0; i<N; ++i)                                   <
  170                                  UpdateMidNode(tree.size()-1, i);                 <
  171                  }                                                                <
  172          }                                                                        <
  173                                                                                   <
  174          int Count()                                                              <
  175          {                                                                        <
  176                  Node x = Canonical(tree.size()-1, 0);                            <
  177                  return x.maxLeft + x.n7;                                         <
  178          }                                                                        <
  179                                                                                   <
  180          void Switch(int L, int R)                                                <
  181          {                                                                        <
  182                  SwitchRec(tree[0].size(), tree.size()-1, 0, L, R);               <
  183          }                                                                        <
  184                                                                                   <
  185          void SwitchRec(int Stride, int lv, int idx, int Raw_L, int Raw_R)        <
  186          {                                                                        <
  187                  // Outside                                                       <
  188                  if( Raw_R <= Stride*idx || Stride*(idx+1) <= Raw_L )             <
  189                          return;                                                  <
  190                                                                                   <
  191                  // Inside                                                        <
  192                  bool& me = tree[lv][idx].switched;                               <
  193                  if( Raw_L <= Stride*idx && Stride*(idx+1) <= Raw_R )             <
  194                  {                                                                <
  195                          me ^= 1;                                                 <
  196                          return;                                                  <
  197                  }                                                                <
  198                                                                                   <
  199                  // Overlap                                                       <
  200                  tree[lv-1][idx*2].switched   ^= me;                              <
  201                  tree[lv-1][idx*2+1].switched ^= me;                              <
  202                  SwitchRec(Stride/2, lv-1, idx*2,   Raw_L, Raw_R);                <
  203                  SwitchRec(Stride/2, lv-1, idx*2+1, Raw_L, Raw_R);                <
  204                  UpdateMidNode(lv, idx);                                          <
  205          }                                                                        <
  206  };                                                                                   124  };
  207  */                                                                               <