Main idea is to split cube into 8 parts and query/add for each one.
Here is my code that have TL6.
Any ideas of how to improve it?
 
import java.io.*;
 
public class P1470 {
    static int [] tree = new int[10000000];
    private static int n;
 
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter writer = new PrintWriter(new OutputStreamWriter(System.out));
 
        n = Integer.valueOf(reader.readLine());
 
        while (true) {
            String line = reader.readLine();
            if (line.startsWith("1")) {
                add(new Ufo(line));
            } else if (line.startsWith("2")){
                writer.println(query(new Region(line)));
            } else {
                break;
            }
        }
        writer.flush();
    }
 
    private static int query(Region region) {
        return doQuery(region, new Region(0, 0, 0, n - 1, n - 1, n - 1), 0);
    }
 
    private static int doQuery(Region q, Region r, int node) {
        if (!r.overlaps(q)) return 0;
        if (q.contains(r)) {
            return tree[node];
        }
        int xMid = (r.x1 + r.x2) / 2;
        int yMid = (r.y1 + r.y2) / 2;
        int zMid = (r.z1 + r.z2) / 2;
 
        return
            doQuery(q, new Region(r.x1, r.y1, r.z1, xMid, yMid, zMid), node * 8 + 1) +
            doQuery(q, new Region(xMid + 1, r.y1, r.z1, r.x2, yMid, zMid), node * 8 + 2) +
            doQuery(q, new Region(xMid + 1, r.y1, zMid + 1, r.x2, yMid, r.z2), node * 8 + 3) +
            doQuery(q, new Region(r.x1, r.y1, zMid + 1, xMid, yMid, r.z2), node * 8 + 4) +
            doQuery(q, new Region(r.x1, yMid + 1, r.z1, xMid, r.y2, zMid), node * 8 + 5) +
            doQuery(q, new Region(xMid + 1, yMid + 1, r.z1, r.x2, r.y2, zMid), node * 8 + 6) +
            doQuery(q, new Region(xMid + 1, yMid + 1, zMid + 1, r.x2, r.y2, r.z2), node * 8 + 7) +
            doQuery(q, new Region(r.x1, yMid + 1, zMid + 1, xMid, r.y2, r.z2), node * 8 + 8);
    }
 
    private static void add(Ufo ufo) {
        doAdd(ufo, new Region(0, 0, 0, n - 1, n - 1, n - 1), 0);
    }
 
    private static void doAdd(Ufo ufo, Region r, int node) {
        if (!r.contains(ufo)) return;
 
        tree[node] += ufo.count;
 
        if (r.isPoint()) return;
 
        int xMid = (r.x1 + r.x2) / 2;
        int yMid = (r.y1 + r.y2) / 2;
        int zMid = (r.z1 + r.z2) / 2;
 
        doAdd(ufo, new Region(r.x1, r.y1, r.z1, xMid, yMid, zMid), node * 8 + 1);
        doAdd(ufo, new Region(xMid + 1, r.y1, r.z1, r.x2, yMid, zMid), node * 8 + 2);
        doAdd(ufo, new Region(xMid + 1, r.y1, zMid + 1, r.x2, yMid, r.z2), node * 8 + 3);
        doAdd(ufo, new Region(r.x1, r.y1, zMid + 1, xMid, yMid, r.z2), node * 8 + 4);
        doAdd(ufo, new Region(r.x1, yMid + 1, r.z1, xMid, r.y2, zMid), node * 8 + 5);
        doAdd(ufo, new Region(xMid + 1, yMid + 1, r.z1, r.x2, r.y2, zMid), node * 8 + 6);
        doAdd(ufo, new Region(xMid + 1, yMid + 1, zMid + 1, r.x2, r.y2, r.z2), node * 8 + 7);
        doAdd(ufo, new Region(r.x1, yMid + 1, zMid + 1, xMid, r.y2, r.z2), node * 8 + 8);
    }
 
    static class Region {
        int x1, y1, z1, x2, y2, z2;
 
        Region(String s) {
            String[] split = s.split("\\s");
            x1 = Integer.valueOf(split[1]);
            y1 = Integer.valueOf(split[2]);
            z1 = Integer.valueOf(split[3]);
            x2 = Integer.valueOf(split[4]);
            y2 = Integer.valueOf(split[5]);
            z2 = Integer.valueOf(split[6]);
        }
 
        Region(int x1, int y1, int z1, int x2, int y2, int z2) {
            this.x1 = x1;
            this.y1 = y1;
            this.z1 = z1;
            this.x2 = x2;
            this.y2 = y2;
            this.z2 = z2;
        }
 
        boolean contains(Ufo ufo) {
            return ufo.x >= x1 && ufo.x <= x2 && ufo.y >= y1 && ufo.y <= y2 && ufo.z >= z1 && ufo.z <= z2;
        }
 
        boolean contains(Region r) {
            return overlaps(r) && x1 <= r.x1 && x2 >= r.x2 && y1 <= r.y1 && y2 >= r.y2 && z1 <= r.z1 && z2 >= r.z2;
        }
 
        boolean overlaps(Region r) {
            return r.x1 <= x2 && r.x2 >= x1 && r.y1 <= y2 && r.y2 >= y1 && r.z1 <= z2 && r.z2 >= z1;
        }
 
        boolean isPoint() {
            return x1 == x2 && y1 == y2 && z1 == z2;
        }
    }
 
    static class Ufo {
        int x, y, z, count;
 
        Ufo(String s) {
            String[] split = s.split("\\s");
            x = Integer.valueOf(split[1]);
            y = Integer.valueOf(split[2]);
            z = Integer.valueOf(split[3]);
            count = Integer.valueOf(split[4]);
        }
    }
}