Looking at this problem, I need to find i, j, k where the sequence has been modified by reversing [i,j-1] and [j,k].
Key observations:
1. Original sequence: a[p] = p
2. After reversal of [i,j-1]: elements i..j-1 are reversed
3. After reversal of [j,k]: elements j..k are reversed
The number of inversions in a subsegment tells me about the structure.
Let me think about properties:
- In a reversed segment [l,r], the number of inversions is (r-l+1)*(r-l)/2
- At boundaries i, j-1, j, k, there are specific inversion patterns
Strategy: Binary search to find the boundaries.
Key insight:
- For any subsegment that's entirely within [i, j-1] or [j, k], it's reversed, so inversions = len*(len-1)/2
- For subsegments crossing the boundary at j: inversions will be high (both parts contribute cross-inversions)
- Outside [i,k], no inversions
I can find the boundaries by:
1. Find i: leftmost position where inversions start (query(p, p+1) = 1 means adjacent pair is inverted)
2. Find k: rightmost such position
3. Find j: the boundary between the two reversed segments
Let me implement binary search:
- Find i: binary search for leftmost l where query(l, l+1) = 1
- Find k: binary search for rightmost l where query(l, l+1) = 1
- Find j: within [i, k], find where the two segments meet
For finding j: query(i, m) for various m. If m < j, inversions = (m-i+1)*(m-i)/2 (fully in first reversed segment). If m >= j, it crosses.
Actually, query(i, j-1) should equal (j-i)*(j-i-1)/2, and query(i, j) will be larger due to cross-inversions.
Let me binary search for j within [i+1, k]: find smallest m where query(i, m) != m*(m-1)/2 ... wait, query(i, m) for m in [i, j-1] should be (m-i+1)*(m-i)/2.
So binary search: find smallest m such that query(i, m) != (m-i+1)*(m-i)/2. That m = j.
```go
package main
import (
"bufio"
"fmt"
"os"
)
var reader *bufio.Reader
var writer *bufio.Writer
func query(l, r int) int {
fmt.Fprintf(writer, "? %d %d\n", l, r)
writer.Flush()
var ans int
fmt.Fscan(reader, &ans)
return ans
}
func main() {
reader = bufio.NewReader(os.Stdin)
writer = bufio.NewWriter(os.Stdout)
defer writer.Flush()
var t int
fmt.Fscan(reader, &t)
for ; t > 0; t-- {
var n int
fmt.Fscan(reader, &n)
// Find i: leftmost position where query(p,p+1)=1
lo, hi := 1, n-1
for lo < hi {
mid := (lo + hi) / 2
if query(mid, mid+1) == 1 {
hi = mid
} else {
lo = mid + 1
}
}
i := lo
// Find k: rightmost position where query(p,p+1)=1
lo, hi = 1, n-1
for lo < hi {
mid := (lo + hi + 1) / 2
if query(mid, mid+1) == 1 {
lo = mid
} else {
hi = mid - 1
}
}
k := lo + 1
// Find j: within [i+1, k], smallest m where query(i,m) != (m-i+1)*(m-i)/2
lo, hi = i+1, k
for lo < hi {
mid := (lo + hi) / 2
length := mid - i + 1
expected := length * (length - 1) / 2
if query(i, mid) == expected {
lo = mid + 1
} else {
hi = mid
}
}
j := lo
fmt.Fprintf(writer, "! %d %d %d\n", i, j, k)
writer.Flush()
}
}
```