#include using namespace std; typedef long double ll; const int MX = (1<<20); bool debug = 1; struct DATA{ int toLeft , toRight; int cnt; ll H; }; DATA data[MX]; int par[MX]; int n , QN; int find_(int x){ if(x == par[x]) return x; return par[x] = find_(par[x]); } ll EPS = 1e-10; int L[MX] , R[MX]; int findLeft(int x){ if(x == L[x]) return x; return L[x] = findLeft(L[x]); } int findRight(int x){ if(x == R[x]) return x; return R[x] = findRight(R[x]); } int linkLeft(int x , int y){ x = findLeft(x) , y = findLeft(y); if(x > y) swap(x , y); if(x != y) L[y] = x; } int linkRight(int x , int y){ x = findRight(x) , y = findRight(y); if(x > y) swap(x , y); if(x != y) R[x] = y; } void merge_(int x , int y){ if(x == 0 || y == 1 + n) return; x = find_(x) , y = find_(y); if(x == y) return; if(abs(data[x].H - data[y].H) > EPS) return; if(x > y) swap(x , y); par[y] = x; data[x].cnt += data[y].cnt; data[x].toRight = max(data[x].toRight , data[y].toRight); data[x].toLeft = min(data[x].toLeft , data[y].toLeft); linkLeft(x , y); linkRight(x , y); //data[x].lessToLeft = min(data[x].lessToLeft , data[y].lessToLeft); //data[x].lessToRight = max(data[x].lessToRight , data[y].lessToRight); } ll inf; void add(int pos , ll V){ if(debug){cout<<"#"<<"addedto"<<' '<= data[find_(rightmost + 1)].H) linkRight(rightmost , rightmost + 1); // data[pos].lessToRight = data[find_(pos + 1)].lessToRight; int leftmost = data[pos].toLeft; if(leftmost != 1) if(data[pos].H >= data[find_(leftmost - 1)].H) linkLeft(leftmost , leftmost - 1); // data[pos].lessToLeft = data[find_(pos - 1)].lessToLeft;*/ } ll find_dif(int pos){ //cout< 1 && arr[j - 1] < arr[j]) L[j] = L[j - 1]; } for(int j = n - 1 ; j ; j--){ if(j != n && arr[j + 1] < arr[j]) R[j] = R[ j + 1 ]; } for(int j = 1 ; j <= n ; j++){ data[j].cnt = 1; data[j].H = arr[j]; data[j].toLeft = j; data[j].toRight = j; } if(debug){for(int j = 1 ; j <= n ; j++) cout<