https://www.luogu.com.cn/problem/P5854
这题1e7的输入,只开500ms时限,太毒瘤了,写标准的笛卡尔树要加了读入优化,改成register ++i要387ms,去掉register写i++要488ms,不开读入优化过不了,可能要改成普通的单调栈,那就没有到模板题的意义了啊
笛卡尔树就是下标是第一维,权值是第二维,前序遍历顺序满足下标顺序,树的结构满足第二维权值小根堆
于是构建笛卡尔树的方法跟单调栈差不多,从左到右去跟前面的比较一下,然后确定他的儿子和父亲是谁
#include<bits/stdc++.h>
namespace FastIO {
const int SIZE = 1 << 16;
char buf[SIZE], obuf[SIZE], str[60];
int bi = SIZE, bn = SIZE, opt;
int read(char *s) {
while (bn) {
for (; bi < bn && buf[bi] <= ' '; bi++);
if (bi < bn) break;
bn = fread(buf, 1, SIZE, stdin);
bi = 0;
}
int sn = 0;
while (bn) {
for (; bi < bn && buf[bi] > ' '; bi++) s[sn++] = buf[bi];
if (bi < bn) break;
bn = fread(buf, 1, SIZE, stdin);
bi = 0;
}
s[sn] = 0;
return sn;
}
bool rd(int& x) {
int n = read(str), bf;
if (!n) return 0;
int i = 0; if (str[i] == '-') bf = -1, i++; else bf = 1;
for (x = 0; i < n; i++) x = x * 10 + str[i] - '0';
if (bf < 0) x = -x;
return 1;
}
};
using namespace FastIO;
using namespace std;
typedef long long ll;
const int maxl=1e7+10;
int n,rt;ll ansl,ansr;
int a[maxl],s[maxl];
struct node
{
int k,val,fa,ls,rs;
}tr[maxl];
inline void prework()
{
tr[0]=node{0,0,0,0,0};
//scanf("%d",&n);
rd(n);
for(int i=1;i<=n;i++)
{
//scanf("%d",&a[i]);
rd(a[i]);
tr[i]=node{i,a[i],0,0,0};
}
}
inline int build(int n)
{
for(int i=1;i<=n;i++)
{
int k=i-1;
while(tr[k].val>tr[i].val)
k=tr[k].fa;
tr[i].fa=k;
tr[i].ls=tr[k].rs;
tr[k].rs=i;
tr[tr[i].ls].fa=i;
}
return tr[0].rs;
}
inline void mainwork()
{
rt=build(n);
ansl=0;ansr=0;
for(int i=1;i<=n;i++)
ansl^=1ll*i*(tr[i].ls+1),ansr^=1ll*i*(tr[i].rs+1);
}
inline void print()
{
printf("%lld %lld\n",ansl,ansr);
}
int main()
{
prework();
mainwork();
print();
return 0;
}