#笛卡尔树#洛谷 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);
}
posted @ 2021-03-05 19:54  lemondinosaur  阅读(56)  评论(0编辑  收藏  举报