Learn Cartesian Tree

Posted by smiley_kool on Wed, 24 Jul 2019 18:54:10 +0200

Cartesian Tree (Summary of Knowledge + Boardsorting)

Cartesian Tree

 

Example 1:hdu-6305

RMQ Similar Sequence

 

[Title]:

IMPORTANT: Defines RMQ(A,l,r) as the minimum I satisfying A[i] = max(A[l],A[l+1],...,A[r]) in sequence A.If any (l,r) satisfies RMQ(A,l,r)=RMQ(B,l,r), then A and B are RMQ Similars.Now that sequence A is shown, each number of sequence B is a real number between 0 and 1. Ask Satisfy the expectation that A is the sum of all numbers in all sequence B of RMQ Similar.

Solution: It is not difficult to see that if A and B are RMQ Similar s, A and B are Cartesian trees isomorphic.Considering that each number in B is a real number between 0 and 1, so the probability of the same number is 0, you can assume that B has different permutations for each number.If the size of each subtree of a Cartesian tree of A is sz[u], then the probability that any B permutation is isomorphic to A isBecause each number in B satisfies a uniform distribution, the expected value is 1/2 and the expected sum is n/2, so the expected sum of all numbers in B that are identical to A is

 


So: sz[i] refers to the size of each subtree of a Cartesian tree.

 

Paste code:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<stack>
 4 using namespace std;
 5 typedef long long ll;
 6 const int N = 1e6 + 5 ;
 7 const int INF = 0x3f3f3f3f;
 8 const int mod = 1e9+7;
 9 inline int read(){
10     int x = 0 , f = 1 ;
11     char c = getchar();
12     while ( c < '0' || c > '9' ) {
13         if( c=='-' ) f = -1 ;
14         c = getchar();
15     }
16     while ( '0' <= c && c <= '9' ){
17         x = x*10 + c-'0';
18         c = getchar();
19     }
20     return x * f ;
21 }
22 typedef struct Node{
23     int val,fa,sz;
24     int L,R;
25     Node(){}
26 }Node;
27 Node t[N];
28 stack<int>st;
29 void Init(int n){
30     for(int i=0;i<=n;i++){
31         t[i].sz = t[i].L = t[i].R = t[i].fa = 0;
32     }
33     t[0].val = INF;
34     while(!st.empty()) st.pop();
35     st.push(0);
36 }
37 
38 void build(int n){
39     int k ;
40     for(int i=1;i<=n;i++){
41         while( !st.empty() && t[st.top()].val < t[i].val )
42             st.pop();
43         k = st.top();
44         t[i].L = t[k].R;
45         t[k].R = i ;
46         t[i].fa = k;
47         t[t[i].L].fa = i ;
48         st.push(i);
49     }
50 }
51 void dfs(int u) {
52     if ( !u ) return ;
53     t[u].sz = 1 ;
54     dfs( t[u].L );
55     dfs( t[u].R );
56     t[u].sz += t[t[u].L].sz
57             + t[t[u].R].sz ;
58 }
59 ll inv[N];
60 void Init() {
61     inv[1] = 1;
62     for (int i = 2; i < N; i++)
63         inv[i] = inv[mod % i] * (mod - mod / i) % mod;
64 }
65 int main()
66 {
67     int T,n;
68     Init();
69     for ( scanf("%d",&T) ; T ; T-- ){
70 
71         n = read();
72         Init(n);
73         for(int i=1;i<=n;i++){
74             t[i].val = read() ;
75         }
76         //puts("####");
77 
78         build(n);
79         dfs(t[0].R);
80 
81         ll ans=n *inv[2]%mod;
82         for(int i=1;i<=n;i++)
83             ans=ans*inv[t[i].sz]%mod;
84 
85         printf("%lld\n",ans);
86     }
87     return 0;
88 }
89 /*
90 3
91 3
92 1 2 3
93 3
94 1 2 1
95 5
96 1 2 3 2 1
97 */
hdu-6305

 

 

[Example 2] poj-2201

Cartesian Tree

Main idea: Bare Cartesian tree, which outputs the parent and son node numbers of each point, does not have zero.

Construct a Cartesian tree and output the tree.

First sort, then use a stack to maintain the node information of the rightmost tree. When inserting, look for the second key, find and insert. The tree below becomes its left subtree.

Then insert a three-case discussion (bottom, middle, new root)

Title Analysis: Note that this topic must output YES, because each pair of keywords given is different, so a unique Cartesian tree can be built, there is no NO case.The sequence number is out of order after sorting. Just pay attention to it. Nothing else.
 1 #include<cstdio>
 2 #include<algorithm>
 3 const int N = 5e4+5;
 4 using namespace std;
 5 typedef struct Node{
 6     int id , L , R , val , key ,fa ;
 7     bool operator < (const Node &rhs )const {
 8         return key < rhs.key ;
 9     }
10 }Node ;
11 Node t[N];
12 int n,L[N],R[N],st[N],Fa[N];
13 void build(){
14     int top = 0 ;
15     st[top] = 1 ;
16     for(int i=2;i<=n;i++){
17         while( top >= 0 && t[st[top]].val > t[i].val )
18             top -- ;
19         if ( top > -1  ){
20             t[i].L = t[st[top]].R;
21             t[st[top]].R = i ;
22             t[i].fa = st[top];
23             t[t[i].L].fa = i ;
24         }else{
25             t[st[0]].fa = i ;
26             t[i].L = st[0];
27         }
28         st[++top] =  i ;
29     }
30 }
31 
32 int main()
33 {
34     while(~scanf("%d",&n)){
35         for(int i=1;i<=n;i++){
36             scanf("%d%d",&t[i].key,&t[i].val);
37             t[i].id = i ;
38             t[i].L = t[i].R = t[i].fa = 0 ;
39         }
40         sort( t+1 , t+1+n ) ;
41         build();
42         for(int i=1;i<=n;i++){
43             Fa[t[i].id] = t[t[i].fa].id;
44             L[t[i].id] = t[t[i].L].id ;
45             R[t[i].id] = t[t[i].R].id ;
46         }
47         puts("YES");
48         for(int i=1;i<=n;i++){
49             printf("%d %d %d\n",Fa[i],L[i],R[i]);
50         }
51     }
52     return 0;
53 }
54 /*
55 
56 7
57 5 4
58 2 2
59 3 9
60 0 5
61 1 3
62 6 6
63 4 11
64 
65 YES
66 2 3 6
67 0 5 1
68 1 0 7
69 5 0 0
70 2 4 0
71 1 0 0
72 3 0 0
73  */
poj - 2201

Topics: PHP