第一行國際慣例——咕咕咕。
第二行——我真的啥啥都不會啊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,我以爲會爆的,但我試了試,直接通分確實會爆
*/