# P6617 find Search

## General meaning

Given length is n n An integer sequence of n, a 1 , a 2 , . . . , a n a_1, a_2, ..., a_n a1, a2,..., an. There are m operations:

pos val means to a p o s a_{pos} apos # changed to v a l val val.

l r inquiry [ l , r ] [l, r] [l,r] interval, does it exist a i + a j = w , ( i ≠ j ) a_i + a_j = w, (i \ne j) ai​+aj​=w,(i​=j).

## Problem solving ideas

thinking

We consider that if there is no modification operation, we ask whether there are two numbers in different positions in an interval at a time w w w. Then we can record the position index of the first qualified number in front of each position, and then judge the maximum value of the interval i n d e x i index_i indexi # is it satisfied i n d e x i ≥ l index_i \ge l indexi ≥ l

Binding will be used to refer to two qualified positions below

Considering the modification operation, we can no longer maintain information in the above way

Let w = x + y and assume that the sequence is x, y, y, y,..., y

In this way, when we modify the first position, we need to modify all subsequent positions. Obviously, it can be stuck O ( n 2 ) O(n^2) The complexity of O(n2) is

The element of each position is only recorded by the nearest element behind it

set up w = x + y w = x + y w=x+y. considering that for the sequence a = { x , y , y , y } a = \{ x, y, y, y \} For a={x,y,y,y}, we only need to bind 1 and 2 positions

There should be no intersection between position intervals recorded by the same element

set up w = x + y w = x + y w=x+y. considering that for the sequence a = { x , x , y , y } a = \{ x, x, y, y \} For a={x,x,y,y}, we just need to bind the 2 and 3 positions

Through the above two conclusions, we find that the numbers bound forward and backward for each position can be uniquely determined. Therefore, when modifying a position, we can remove / add the impact of the current position through constant operations

Segment tree

We find that the essence of query is to query the maximum value of interval, so we can use segment tree to maintain the maximum value dynamically

For the modification operation, we can maintain the precursor and successor (binding) of each location

## AC code

```#include <bits/stdc++.h>
#define rep(i, n) for (int i = 1; i <= (n); ++i)
using namespace std;
typedef long long ll;
const int N = 5E5 + 10;

int w[N];
struct node { //Segment tree dynamic maintenance interval maximum
int l, r;
int fmax;
}t[N << 2];
void pushup(int x) { t[x].fmax = max(t[x << 1].fmax, t[x << 1 | 1].fmax); }

void build(int l, int r, int x = 1) {
t[x] = { l, r, 0 };
if (l == r) return;
int mid = l + r >> 1;
build(l, mid, x << 1), build(mid + 1, r, x << 1 | 1);
}

void modify(int a, int c, int x = 1) {
if (t[x].l == t[x].r) {
t[x].fmax = c;
return;
}
int mid = t[x].l + t[x].r >> 1;
modify(a, c, x << 1 | (a > mid));
pushup(x);
}

int ask(int l, int r, int x = 1) {
if (l <= t[x].l and r >= t[x].r) return t[x].fmax;
int mid = t[x].l + t[x].r >> 1;
int res = 0;
if (l <= mid) res = ask(l, r, x << 1);
if (r > mid) res = max(res, ask(l, r, x << 1 | 1));
return res;
}

set<int> st[N]; //Maintain where each value appears
int getnext(int x, int pos) { //Find strict successors
auto it = st[x].upper_bound(pos);
if (it == st[x].end()) return 0;
return *it;
}
int getprev(int x, int pos) { //Find strict precursors
auto it = st[x].lower_bound(pos);
if (it == st[x].begin()) return 0;
return *--it;
}
int main()
{
int n, m, W; cin >> n >> m >> W;
build(1, n);
rep(i, n) {
scanf("%d", &w[i]);
int other = W - w[i];
if (!st[other].empty()) { //Prevent = = W/2
int qaq = *st[other].rbegin(); //Element position to pair
}
st[w[i]].insert(i);
}

int cou = 0;
rep(i, m) {
int tp; scanf("%d", &tp);
if (tp == 1) {
int a, c; scanf("%d %d", &a, &c);
if (c == w[a]) continue;

if (posprev) { //There's something ahead
int posnext = getnext(w[a], a);
if (posnext and !ask(posnext, posnext)) { //There is something behind and no link
modify(posnext, posprev);
}
modify(a, 0);
}

posprev = getprev(w[a], a); // Previous position

}
}

st[w[a]].erase(a);
w[a] = c;
st[w[a]].insert(a);

posprev = getprev(W - w[a], a);
if (posprev) {
modify(a, posprev);
}
modify(a, posprev);
}
}

int posnext = getnext(W - w[a], a);
if (posnext) {

if (posprev < a) {  // posprev(0)   a   posnext
modify(posnext, a);
}
}
}
else {
int l, r; scanf("%d %d", &l, &r);
l ^= cou, r ^= cou;