Time: Refer to the answer

After reading the title, the first thing that comes to mind is that dp cannot escape

But writing the conversion equation requires some skill

Observe that dp[1][1] = matrix[0][0] ^ matrix[0][1] ^ matrix[1][0] ^ matrix[1][1]

Then use the property of XOR

The same value is XORed to 0, and any value XORed with 0 is itself

Can be written as

dp[1][1] = matrix[0][0] ^ (matrix[0][1] ^ matrix[0][0]) ^ (matrix[1][0] ^ matrix[1][0]) ^ matrix[1][1]

Then get

dp[i][j] = dp[i - 1][j - 1] ^ dp[i][j - 1] ^ dp[i - 1][j] ^ matrix[i][j]

(This is a technique I didn’t think of. If you can draw a picture, you can figure it out.

After the XOR operation of the region (1, 2) and (2, 1), the overlapping parts are eliminated.

The overlapping part is exactly the area of (1, 1), so we can XOR (1, 1) to compensate

const swap = function (arr,i,j) {
    [arr[i],arr[j]] = [arr[j],arr[i]]
}
class MaxHeap {
    constructor() {
        this.count = 0        this.data = new Array(this.count + 1)
    }
    shiftUp(k) {
        // Put the new elements up while(k>=1) {
            let father = Math.floor(k / 2)
            if (this.data[k] > this.data[father]) {
                swap(this.data,k,father)
                k = father
            } else {
                break            }
        }
    }
    shiftDown(k) {
        while( k * 2  <= this.count) { // Indicates that k has children let j = k
            if (k * 2 + 1 <= this.count && this.data[k * 2 + 1] > this.data[k] && this.data[k * 2 + 1] > this.data[k * 2]) {
                j = k * 2 + 1            } else if (this.data[k * 2] > this.data[k]) {
                j = k * 2            } else {
                break            }
            swap(this.data,j,k)
            k = j
        }
    }
    size() {
        return this.count    }
    isEmpty() {
        return this.count === 0    }
    insert(item) {
        this.data[++this.count] = item
        this.shiftUp(this.count)
    }
    extractMax() {
        if (this.count < 0) return
        let ret = this.data[1]
        swap(this.data,1,this.count--)
        this.shiftDown(1)
        return ret
    }
}
var kthLargestValue = function(matrix, k) {
    var maxheap = new MaxHeap()
    var row = matrix.length    var col = matrix[0].length    var dp = [[matrix[0][0]]]
    maxheap.insert(matrix[0][0])
    for(let j = 1; j < col ; j ++) {
        dp[0][j] = dp[0][j - 1] ^ matrix[0][j]
        maxheap.insert(dp[0][j])
    }
    for(let i = 1 ; i < row ; i ++) {
        for(let j = 1 ; j < col; j ++) {
            if (!dp[i]) {
                dp[i] = []
                dp[i][0] = dp[i - 1][0] ^ matrix[i][0]
                maxheap.insert(dp[i][0])
            }
            dp[i][j] = dp[i - 1][j - 1] ^ dp[i][j - 1] ^ dp[i - 1][j] ^ matrix[i][j]
            maxheap.insert(dp[i][j])
        }
    }
    var res = ''    while(k > 0) {
        res = maxheap.extractMax()
        k--    }
    return res
};

Then K is large, so we should use the minimum heap. Here we use the maximum heap, but it is not a big problem.

Time: Refer to the answer

After reading the title, the first thing that comes to mind is that dp cannot escape

But writing the conversion equation requires some skill

Observe that dp[1][1] = matrix[0][0] ^ matrix[0][1] ^ matrix[1][0] ^ matrix[1][1]

Then use the property of XOR

The same value is XORed to 0, and any value XORed with 0 is itself

Can be written as

dp[1][1] = matrix[0][0] ^ (matrix[0][1] ^ matrix[0][0]) ^ (matrix[1][0] ^ matrix[1][0]) ^ matrix[1][1]

Then get

dp[i][j] = dp[i - 1][j - 1] ^ dp[i][j - 1] ^ dp[i - 1][j] ^ matrix[i][j]

(This is a technique I didn’t think of. If you can draw a picture, you can figure it out.

After the XOR operation of the region (1, 2) and (2, 1), the overlapping parts are eliminated.

The overlapping part is exactly the area of (1, 1), so we can XOR (1, 1) to compensate

const swap = function (arr,i,j) {
    [arr[i],arr[j]] = [arr[j],arr[i]]
}
class MaxHeap {
    constructor() {
        this.count = 0        this.data = new Array(this.count + 1)
    }
    shiftUp(k) {
        // Put the new elements up while(k>=1) {
            let father = Math.floor(k / 2)
            if (this.data[k] > this.data[father]) {
                swap(this.data,k,father)
                k = father
            } else {
                break            }
        }
    }
    shiftDown(k) {
        while( k * 2  <= this.count) { // Indicates that k has children let j = k
            if (k * 2 + 1 <= this.count && this.data[k * 2 + 1] > this.data[k] && this.data[k * 2 + 1] > this.data[k * 2]) {
                j = k * 2 + 1            } else if (this.data[k * 2] > this.data[k]) {
                j = k * 2            } else {
                break            }
            swap(this.data,j,k)
            k = j
        }
    }
    size() {
        return this.count    }
    isEmpty() {
        return this.count === 0    }
    insert(item) {
        this.data[++this.count] = item
        this.shiftUp(this.count)
    }
    extractMax() {
        if (this.count < 0) return
        let ret = this.data[1]
        swap(this.data,1,this.count--)
        this.shiftDown(1)
        return ret
    }
}
var kthLargestValue = function(matrix, k) {
    var maxheap = new MaxHeap()
    var row = matrix.length    var col = matrix[0].length    var dp = [[matrix[0][0]]]
    maxheap.insert(matrix[0][0])
    for(let j = 1; j < col ; j ++) {
        dp[0][j] = dp[0][j - 1] ^ matrix[0][j]
        maxheap.insert(dp[0][j])
    }
    for(let i = 1 ; i < row ; i ++) {
        for(let j = 1 ; j < col; j ++) {
            if (!dp[i]) {
                dp[i] = []
                dp[i][0] = dp[i - 1][0] ^ matrix[i][0]
                maxheap.insert(dp[i][0])
            }
            dp[i][j] = dp[i - 1][j - 1] ^ dp[i][j - 1] ^ dp[i - 1][j] ^ matrix[i][j]
            maxheap.insert(dp[i][j])
        }
    }
    var res = ''    while(k > 0) {
        res = maxheap.extractMax()
        k--    }
    return res
};

If K is large, a min-heap should be used. Here, a max-heap is used, but it’s not a big deal.