public static int trapRainWater(int[][] heights) {
   // write your code here
   Compare cp = new Compare();
   PriorityQueue<List<Integer>> pq = new PriorityQueue<List<Integer>>(cp);
   boolean[][] visited = new boolean[heights.length][heights[0].length];
   for (int row = 0; row < heights.length; row++) {
     pq.offer(Arrays.asList(heights[row][0], row, 0));
     visited[row][0] = true;
     pq.offer(Arrays.asList(heights[row][heights[0].length - 1], row, heights[0].length - 1));
     visited[row][visited[0].length - 1] = true;
   }
   for (int col = 1; col < heights[0].length - 1; col++) {
     pq.offer(Arrays.asList(heights[0][col], 0, col));
     visited[0][col] = true;
     pq.offer(Arrays.asList(heights[heights.length - 1][col], heights.length - 1, col));
     visited[heights.length - 1][col] = true;
   }
   int ans = 0;
   int[] dirx = {1, -1, 0, 0};
   int[] diry = {0, 0, 1, -1};
   while (!pq.isEmpty()) {
     List<Integer> smallest = pq.poll();
     int x = smallest.get(1);
     int y = smallest.get(2);
     // if (!visited[x][y]) {
     for (int i = 0; i < 4; i++) {
       int newX = x + dirx[i];
       int newY = y + diry[i];
       if (newX >= 0
           && newY < heights.length
           && newY >= 0
           && newY < heights[0].length
           && !visited[newX][newY]) {
         if (heights[newX][newY] < smallest.get(0)) {
           System.out.println("x:" + newX + " y: " + newY);
           ans += smallest.get(0) - heights[newX][newY];
           heights[newX][newY] = smallest.get(0);
         }
         visited[newX][newY] = true;
         pq.offer(Arrays.asList(heights[newX][newY], newX, newY));
       }
     }
     // }
   }
   return ans;
 }
Exemple #2
0
  private void dfs(int cur, int fa) {
    f[cur] = g[cur] = MIN_VALUE;
    int cntchd = 0;

    for (Graph.Edge e : tree.adj[cur]) {
      if (e.b == fa) continue;
      cntchd++;
      dfs(e.b, cur);
    }

    if (cntchd == 0) {
      f[cur] = MIN_VALUE;
      g[cur] = 0;
      return;
    }

    List<Integer> chdList = new ArrayList<Integer>();
    int res0 = 0;
    int gc0 = 0;
    for (Graph.Edge e : tree.adj[cur]) {
      if (e.b == fa) continue;
      if (f[e.b] == MIN_VALUE && g[e.b] == MIN_VALUE) throw new RuntimeException();
      if (f[e.b] == MIN_VALUE) {
        res0 += g[e.b];
        gc0++;
      } else if (g[e.b] == MIN_VALUE) {
        res0 += f[e.b] + 1;
      } else chdList.add(e.b);
    }

    // Below code is useless, yet more illustrating.
    Integer[] chds = chdList.toArray(new Integer[0]);
    Arrays.sort(
        chds,
        new Comparator<Integer>() {
          // @Override
          public int compare(Integer o1, Integer o2) {
            int x = g[o1] - f[o1] - 1;
            int y = g[o2] - f[o2] - 1;
            return -x + y;
          }
        });
    for (int gc = 0; gc <= chds.length; ++gc) {
      int res = res0;
      for (int i = 0; i < gc; ++i) res += g[chds[i]];
      for (int i = gc; i < chds.length; ++i) res += f[chds[i]] + 1;
      if ((gc + gc0) % 2 == 0) g[cur] = Math.max(g[cur], res);
      else f[cur] = Math.max(f[cur], res);
    }
  }
 private void solve() {
   int n = in.nextInt();
   int m = in.nextInt();
   int[] is = in.nextIntArray(n);
   P[] ps = new P[m];
   for (int i = 0; i < m; i++) {
     int l = in.nextInt() - 1;
     int r = in.nextInt();
     ps[i] = new P(l, r, i);
   }
   Arrays.sort(ps);
   for (int i = 0; i * B < m; i++) {
     Arrays.sort(
         ps,
         i * B,
         Math.min(i * B + B, m),
         new Comparator<P>() {
           @Override
           public int compare(P o1, P o2) {
             return o1.r - o2.r;
           }
         });
   }
   long[] res = new long[m];
   long ans = 1;
   int l = 0;
   int r = 0;
   int[] cnt = new int[C];
   int num = 0;
   int[] inv = new int[n + 1];
   for (int i = 1; i <= n; i++) {
     inv[i] = (int) Num.inv(i, M);
   }
   for (P p : ps) {
     while (l > p.l) {
       try {
         ans *= num + 1;
         ans %= M;
         ans *= inv[cnt[is[l - 1]] + 1];
         ans %= M;
         cnt[is[l - 1]]++;
         num++;
         l--;
       } catch (ArrayIndexOutOfBoundsException e) {
         for (; ; ) ;
       }
     }
     while (r < p.r) {
       ans *= num + 1;
       ans %= M;
       ans *= inv[cnt[is[r]] + 1];
       ans %= M;
       cnt[is[r]]++;
       num++;
       r++;
     }
     while (l < p.l) {
       ans *= inv[num];
       ans %= M;
       ans *= cnt[is[l]];
       ans %= M;
       cnt[is[l]]--;
       num--;
       l++;
     }
     while (r > p.r) {
       ans *= inv[num];
       ans %= M;
       ans *= cnt[is[r - 1]];
       ans %= M;
       cnt[is[r - 1]]--;
       num--;
       r--;
     }
     res[p.id] = ans;
   }
   for (long i : res) out.println(i);
 }
 public byte[] getBytes(int offset, int length) {
   return Arrays.copyOfRange(bytes, offset, offset + length);
 }
 public String getString(int offset, int length) {
   return new String(Arrays.copyOfRange(bytes, offset, offset + length));
 }