0%

笛卡尔树

例题

Equivalent Prefixes-前缀笛卡尔树

序列u,v 对于[1,ans][1,ans]上所有的[L,R][L,R](1<=L<=R<=ans<=n)(1<=L<=R<=ans<=n)

都满足RMQ(u,L,R)=RMQ(v,L,R)RMQ(u,L,R)=RMQ(v,L,R)

max(ans)max(ans);

分析:考虑判断两个序列的前缀笛卡尔树是否相等

注意,如果前缀笛卡尔树相等,则可以判断每一个栈深都相同,想想为什么?、

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <bits/stdc++.h>
#include<stdint.h>
#define int long long
#define scan(n) scanf("%lld", &(n))
#define scann(n, m) scanf("%lld%lld", &(n), &(m))
#define scannn(a, b, c) scanf("%lld%lld%lld", &(a), &(b), &(c))
#define prin(n) printf("%lld", (n))
#define pb push_back
#define mp make_pair
#define ms(a) memset(a, 0, sizeof(a))
#define fo(i, a, b) for (int i = (a); i <= (b); i++)
#define ro(i, a, b) for (int i = (a); i >= (b); i--)
const int inf = 0x3f3f3f3f;
using namespace std;
const int maxn = 1e5+100;
int n;
int a[maxn],b[maxn];
int s1[maxn],s2[maxn];
int32_t main() {
while(scan(n)!=EOF){
fo(i,1,n)scan(a[i]);
fo(i,1,n)scan(b[i]);
int head1=1,head2=1,tail1=1,tail2=1;
s1[head1]=s2[head2]=inf;
int maxpos=1;
fo(i,1,n){
while(head1<=tail1&&s1[tail1]>a[i])tail1--;
while(head2<=tail2&&s2[tail2]>b[i])tail2--;
if(tail1!=tail2)break;
s1[++tail1]=a[i],s2[++tail2]=b[i];
maxpos=i;
}
cout<<maxpos<<endl;
}
return 0;
}

笛卡尔树习题

http://acm.hdu.edu.cn/showproblem.php?pid=6305
https://blog.csdn.net/zhaiqiming2010/article/details/80245872