第一行国际惯例——咕咕咕。
第二行——我真的啥啥都不会啊qwq。
笛卡尔树:
1.二叉树
2.从数列中构造时可以在线性时间内完成,而且可以找到数列中的最近小数
3.key值——每个节点的左子树比其小,右子树比其大;value——每个节点都比其子树的value大
4.用单调栈进行维护,始终保存的是右链,即:根,右儿子,右儿子的右儿子……并且从栈顶到栈底,key依次减小
5.多用于解决范围搜索问题(反正我也不太会,不过你想,栈里面是大小顺序存放,找top 1、top 2……top k很方便
但是这题我用单调栈做的qwq。
先附题目链接暑期多校A.Equivalent Prefixes
题目大意:
有两个数组a和b,每个数组都有n个不同的元素。找到最大的p(p<=n),使得a,b等价。
等价的定义是R M Q(a,l,r)= R M Q(b,l,r),对全部的1<=l<=r<=n都成立,RMQ表示在l到r内最小元素的索引。
下附代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <stack>
using namespace std;
int main()
{
int t;
int a[100005],b[100005];
while(~scanf("%d",&t))
{
stack<int>s1,s2;
int flag = 0;
for(int i = 1; i <= t; ++i) scanf("%d",&a[i]);
for(int i = 1; i <= t; ++i) scanf("%d",&b[i]);
for(int i = 1; i <= t; ++i)
{
while(s1.empty() != 1&&s1.top() > a[i]) s1.pop();
while(s2.empty() != 1&&s2.top() > b[i]) s2.pop();
s1.push(a[i]);
s2.push(b[i]);//每次都只保存当前的比栈顶大的第二小值
if(s1.size() != s2.size())
{
printf("%d\n",i-1);
flag = 1;
break;
}//存的个数相等时,表示最小值的索引相同,才会存入栈,否则为不相同
}
if(!flag)
printf("%d\n",t);
}
return 0;
}
附一下其他题的思路,我也不会我就记了记队里师哥or队友的思路,以及数学真的好重要啊,%ryc师哥。
/*
第一场
A题,笛卡尔树
B题,利用积分中分母拆分的方法,拆成多个多项式的和
C题,有条件限制的极值,拉格朗日乘数法,化简后的式子可能有不满足条件,需要排序,小的令p为0
E题,dp,利用路径能否组成ab/ba来进行转移,有些状态会被限制,需要判断 题解
F题,三角形的面积中心三等分面积,中心移动,对比面积变化可得在每个区域里应该选择三个三角形中的哪个三角形,选特殊三角形计算,然后即可得出选每部分的概率,求期望可得出与三角形面积的关系
J题,我队友用java做的,咱也不知道咱也没问upd:好了我去做了一下,我会了,如果用c++的话需要处理一下,只取小数部分,就用zx = x/a; zy = y/b;先比较整数部分,然后xx = x%a; yy = y%b;再通分比较就行。(数据还是不够大鸭qwq,我以为会爆的,但我试了试,直接通分确实会爆
*/