#笛卡尔树#洛谷 3793 由乃救爷爷
题目
询问区间最大值,所有数据随机生成
分析
建一棵笛卡尔树,实际上常数不大可过
代码
#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
typedef unsigned uit;
typedef unsigned long long ull;
const int N=20000011;
int n,m,a[N]; ull ans;
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
struct Descartes{
int st[N],ls[N],rs[N],top,last,root;
inline void build(){
top=0,last=0;
for (rr int i=1;i<=n;++i){
while (a[st[top]]<a[i]) --top;
if (top<last) ls[i]=st[top+1];
if (top) rs[st[top]]=i;
st[last=++top]=i;
}
root=st[1];
}
inline signed query(int l,int r){
rr int now=root;
while (1){
if (l<=now&&now<=r) return a[now];
now=r<now?ls[now]:rs[now];
}
}
}Tre;
namespace GenHelper
{
uit z1,z2,z3,z4,b;
inline uit Ran()
{
b=((z1<<6)^z1)>>13;
z1=((z1&4294967294U)<<18)^b;
b=((z2<<2)^z2)>>27;
z2=((z2&4294967288U)<<2)^b;
b=((z3<<13)^z3)>>21;
z3=((z3&4294967280U)<<7)^b;
b=((z4<<3)^z4)>>12;
z4=((z4&4294967168U)<<13)^b;
return (z1^z2^z3^z4);
}
}
inline void Sand(uit x)
{
using namespace GenHelper;
z1=x; z2=(~x)^0x233333333U;
z3=x^0x1234598766U; z4=(~x)+51;
}
inline signed Get()
{
using namespace GenHelper;
rr int a=Ran()&32767;
rr int b=Ran()&32767;
return a*32768+b;
}
signed main(){
n=iut(),m=iut(),Sand(iut()),a[0]=2e9;
for (rr int i=1;i<=n;++i) a[i]=Get();
Tre.build();
for (rr int i=1;i<=m;++i){
rr int l=Get()%n+1,r=Get()%n+1;
if (l>r) l^=r,r^=l,l^=r;
ans+=Tre.query(l,r);
}
return !printf("%llu",ans);
}