CF1156E Special Segments of Permutation

Ideas: Cartesian tree? (It does not seem to have to build it, but you can be better understood)

Submission: 2

Wrong because: There is no judgment about whether his son is empty cause it to back up T

answer:

Cartesian tree construction, consider how to calculate the answer:
first position of each pretreatment values occurring \ (POS [] \) ;
for each of a left and right son point, he is located in the original sequence \ (MX \) Given the nature of Descartes tree, is greater than all elements of a sub-tree own any. In this way, we traverse the elements of his son in light of \ (VL \) , query \ (pos [mx-vl] \) whether the baryon tree.
In fact, it can not contribute directly to obtain the maximum value for each point as to extend to the left and right sections, enumeration small enough intervals.
Complexity \ (O (nlogn) \) , because the tree-like cross-sectional, up to each point will jump up \ (logN \) strips light side; and a point is calculated, and only the light in the enumeration when the subtree; In fact, similar dsu on tree.
Of course, the complexity of the achievements of the practice, although not explain the difference, but the essence is the same,

Code:

#include<bits/stdc++.h>
#define R register int
using namespace std;
namespace Luitaryi {
inline int g() { R x=0,f=1;
  register char ch; while(!isdigit(ch=getchar())) f=ch=='-'?-1:f;
  do x=x*10+(ch^48); while(isdigit(ch=getchar())); return x*f;
} const int N=250010;
int n,rt,a[N],pos[N],ans;
struct node {int ls,rs,sz,l,r;} t[N];
#define ls(tr) t[tr].ls
#define rs(tr) t[tr].rs
#define sz(tr) t[tr].sz
#define l(tr) t[tr].l
#define r(tr) t[tr].r
int stk[N],top;
inline void calc(int tr,int rn,int mx) {
  for(R i=l(tr);i<=r(tr);++i) 
    ans+=(pos[mx-a[i]]>=l(rn)&&pos[mx-a[i]]<=r(rn));
}
inline void dfs(int tr) {
  sz(tr)=1,l(tr)=r(tr)=tr;
  if(ls(tr)) dfs(ls(tr)),l(tr)=l(ls(tr)); 
  if(rs(tr)) dfs(rs(tr)),r(tr)=r(rs(tr));
  if(!ls(tr)||!rs(tr)) return ;
  sz(tr)=sz(ls(tr))+sz(rs(tr));
  if(sz(ls(tr))<sz(rs(tr))) calc(ls(tr),rs(tr),a[tr]);
  else calc(rs(tr),ls(tr),a[tr]);
}
inline void main() {
  n=g(); for(R i=1;i<=n;++i) a[i]=g(),pos[a[i]]=i; 
  stk[++top]=0,a[0]=1e9;
  for(R i=1;i<=n;++i) { R lst=0;
    while(a[stk[top]]<a[i]) lst=stk[top],--top;
    ls(i)=lst,rs(stk[top])=i; stk[++top]=i;
  } rt=stk[2];
  dfs(rt); printf("%d\n",ans);
}
} signed main() {Luitaryi::main(); return 0;}

2019.09.15
61

Guess you like

Origin www.cnblogs.com/Jackpei/p/11525095.html