Advertisement
Guest User

Untitled

a guest
Jul 6th, 2013
491
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 2.26 KB | None | 0 0
  1. import java.util.Random;
  2.  
  3. public class SegmentTreeSum {
  4.  
  5.     int n;
  6.     int[] sum;
  7.  
  8.     public SegmentTreeSum(int n) {
  9.         this.n = n;
  10.         sum = new int[Integer.highestOneBit(n) << 2];
  11.     }
  12.  
  13.     void pushDelta(int root, int left, int right) {
  14.         int middle = (left + right) / 2;
  15.         int len = (right - left + 1);
  16.         int delta = (sum[root] - sum[2 * root + 1] - sum[2 * root + 2]) / len;
  17.         sum[2 * root + 1] += delta * (middle - left + 1);
  18.         sum[2 * root + 2] += delta * (right - middle);
  19.     }
  20.  
  21.     public int sum(int a, int b) {
  22.         return sum(a, b, 0, 0, n - 1);
  23.     }
  24.  
  25.     int sum(int a, int b, int root, int left, int right) {
  26.         if (a > right || b < left)
  27.             return 0;
  28.         if (a <= left && right <= b)
  29.             return sum[root];
  30.         pushDelta(root, left, right);
  31.         return sum(a, b, root * 2 + 1, left, (left + right) / 2) + sum(a, b, root * 2 + 2, (left + right) / 2 + 1, right);
  32.     }
  33.  
  34.     public void add(int a, int b, int value) {
  35.         add(a, b, value, 0, 0, n - 1);
  36.     }
  37.  
  38.     void add(int a, int b, int value, int root, int left, int right) {
  39.         if (a > right || b < left)
  40.             return;
  41.         if (a <= left && right <= b) {
  42.             sum[root] += value * (right - left + 1);
  43.             return;
  44.         }
  45.         pushDelta(root, left, right);
  46.         int middle = (left + right) / 2;
  47.         add(a, b, value, 2 * root + 1, left, middle);
  48.         add(a, b, value, 2 * root + 2, middle + 1, right);
  49.         sum[root] = sum[2 * root + 1] + sum[2 * root + 2];
  50.     }
  51.  
  52.     // Random test
  53.     public static void main(String[] args) {
  54.         Random rnd = new Random();
  55.         for (int step = 0; step < 1000; step++) {
  56.             int n = rnd.nextInt(50) + 1;
  57.             int[] x = new int[n];
  58.             SegmentTreeSum t = new SegmentTreeSum(n);
  59.             for (int i = 0; i < 1000; i++) {
  60.                 int b = rnd.nextInt(n);
  61.                 int a = rnd.nextInt(b + 1);
  62.                 int cmd = rnd.nextInt(3);
  63.                 if (cmd == 0) {
  64.                     int delta = rnd.nextInt(100) - 50;
  65.                     t.add(a, b, delta);
  66.                     for (int j = a; j <= b; j++)
  67.                         x[j] += delta;
  68.                 } else if (cmd == 1) {
  69.                     int res1 = t.sum(a, b);
  70.                     int res2 = x[a];
  71.                     for (int j = a + 1; j <= b; j++)
  72.                         res2 += x[j];
  73.                     if (res1 != res2)
  74.                         throw new RuntimeException("error");
  75.                 } else {
  76.                     for (int j = 0; j < n; j++) {
  77.                         if (t.sum(j, j) != x[j])
  78.                             throw new RuntimeException("error");
  79.                     }
  80.                 }
  81.             }
  82.         }
  83.         System.out.println("Test passed");
  84.     }
  85. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement