#4864. [BeiJing 2017 Wc]神秘物质 [FHQ Treap]

这题其实挺简单的,有个东西可能稍微难维护了一点点。。

\(merge\ x\ e\) 当前第 \(x\) 个原子和第 \(x+1\) 个原子合并,得到能量为 \(e\) 的新原子;
\(insert\ x\ e\) 在当前第 \(x\) 个原子和第 \(x+1\) 个原子之间插入一个能量为 \(e\) 的新原子。
\(max\ x\ y\) 当前第 \(x\) 到第 \(y\) 个原子之间的任意子区间中区间极差的最大值;
\(min\ x\ y\) 当前第 \(x\) 到第 \(y\) 个原子之间的任意子区间中区间极差的最小值。

极差最大值其实很显然是个区间 \(max - min\)
极差最小的区间呢,长度至少为 \(2\) 也必须为 \(2\)
至于证明的话
考虑 \(x,y,z\)

如果 \(x\)\(z\) 的差的绝对值是解,那么 \(|x-y|\) 或者 \(|y-z|\) 一定更优

因为 \(x \leq y \leq z\) 才符合这种情况。

所以随便写写,把相邻两个的差变成后一个点的值,随便写写就可以了。

// by Isaunoya
#include <bits/stdc++.h>
using namespace std;
#define rep(i, x, y) for (register int i = (x); i <= (y); ++i)
#define Rep(i, x, y) for (register int i = (x); i >= (y); --i)

const int _ = 1 << 21;
struct I {
	char fin[_], *p1 = fin, *p2 = fin;
	inline char gc() {
		return (p1 == p2) && (p2 = (p1 = fin) + fread(fin, 1, _, stdin), p1 == p2) ? EOF : *p1++;
	}
	inline I& operator>>(int& x) {
		bool sign = 1;
		char c = 0;
		while (c < 48) ((c = gc()) == 45) && (sign = 0);
		x = (c & 15);
		while ((c = gc()) > 47) x = (x << 1) + (x << 3) + (c & 15);
		x = sign ? x : -x;
		return *this;
	}
	inline I& operator>>(double& x) {
		bool sign = 1;
		char c = 0;
		while (c < 48) ((c = gc()) == 45) && (sign = 0);
		x = (c - 48);
		while ((c = gc()) > 47) x = x * 10 + (c - 48);
		if (c == '.') {
			double d = 1.0;
			while ((c = gc()) > 47) d = d * 0.1, x = x + (d * (c - 48));
		}
		x = sign ? x : -x;
		return *this;
	}
	inline I& operator>>(char& x) {
		do
			x = gc();
		while (isspace(x));
		return *this;
	}
	inline I& operator>>(string& s) {
		s = "";
		char c = gc();
		while (isspace(c)) c = gc();
		while (!isspace(c) && c != EOF) s += c, c = gc();
		return *this;
	}
} in;
struct O {
	char st[100], fout[_];
	signed stk = 0, top = 0;
	inline void flush() {
		fwrite(fout, 1, top, stdout), fflush(stdout), top = 0;
	}
	inline O& operator<<(int x) {
		if (top > (1 << 20)) flush();
		if (x < 0) fout[top++] = 45, x = -x;
		do
			st[++stk] = x % 10 ^ 48, x /= 10;
		while (x);
		while (stk) fout[top++] = st[stk--];
		return *this;
	}
	inline O& operator<<(char x) {
		fout[top++] = x;
		return *this;
	}
	inline O& operator<<(string s) {
		if (top > (1 << 20)) flush();
		for (char x : s) fout[top++] = x;
		return *this;
	}
} out;
#define pb emplace_back
#define fir first
#define sec second

template < class T > inline void cmax(T & x , const T & y) {
	(x < y) && (x = y) ;
}
template < class T > inline void cmin(T & x , const T & y) {
	(x > y) && (x = y) ;
}


int n , m , rt = 0 ;
const int N = 2e5 + 10 ;
int a[N] ;
const int inf = 0x7fffffff ;
int rnd[N] , val[N] , mx[N] , mn[N] , ch[N][2] , sz[N] ;
int cnt = 0 ;
#define ls(x) ch[x][0]
#define rs(x) ch[x][1]
int newnode(int v) {
	++ cnt ;
	val[cnt] = mx[cnt] = mn[cnt] = v ;
	rnd[cnt] = rand() ;
	sz[cnt] = 1 ;
	return cnt ;
}
int t[N] , s[N] ;
void pushup(int rt) {
	mx[rt] = mn[rt] = val[rt] ;
	if(ls(rt)) cmin(mn[rt] , mn[ls(rt)]) , cmax(mx[rt] , mx[ls(rt)]) ;
	if(rs(rt)) cmin(mn[rt] , mn[rs(rt)]) , cmax(mx[rt] , mx[rs(rt)]) ;
	sz[rt] = sz[ls(rt)] + sz[rs(rt)] + 1 ;
	t[rt] = min(t[ls(rt)] , t[rs(rt)]) , cmin(t[rt] , s[rt]) ;
}
int merge(int u , int v) {
	if(! u || ! v) return u | v ;
	if(rnd[u] < rnd[v]) {
		rs(u) = merge(rs(u) , v) ;
		pushup(u) ;
		return u ;
	} else {
		ls(v) = merge(u , ls(v)) ;
		pushup(v) ;
		return v ;
	}
}
void split(int cur , int k , int & u , int & v) {
	if(! cur) {
		u = v = 0 ;
		return ;
	}
	if(k <= sz[ls(cur)]) {
		v = cur ;
		split(ls(v) , k , u , ls(v)) ;
	} else {
		u = cur ;
		split(rs(u) , k - sz[ls(u)] - 1 , rs(u) , v) ;
	}
	pushup(cur) ;
}
void ins(int k , int v) {
	int x , y , z , xx ;
	split(rt , k - 1 , x , y) ;
	split(y , 1 , y , z) ;
	split(z , 1 , z , xx) ;
	int now = newnode(v) ;
	t[now] = s[now] = abs(val[now] - val[y]) ;
	if(! y) {
		t[now] = s[now] = inf ;
	}
	t[z] = s[z] = abs(val[z] - val[now]) ;
	if(! z) {
		t[z] = s[z] = inf ;
	}
	rt = merge(merge(merge(merge(x , y) , now) , z) , xx) ;
}
void _merge(int k , int v) {
	int x , y , z , xx ;
	split(rt , k - 1 , x , y) ;
	split(y , 1 , y , z) ;
	split(z , 1 , z , xx) ;
	rt = merge(x , xx) ;
	ins(k - 1 , v) ;
}
int qrymax(int l , int r) {
	int x , y , z ;
	split(rt , r , x , z) ;
	split(x , l - 1 , x , y) ;
	int res = mx[y] - mn[y] ;
	rt = merge(merge(x , y) , z) ;
	return res ;
}
int qrymin(int l , int r) {
	++ l ;
	int x , y , z ;
	split(rt , r , x , z) ;
	split(x , l - 1 , x , y) ;
	int res = t[y] ;
	rt = merge(merge(x , y) , z) ;
	return res ;
}
void dfs(int u) {
	if(ls(u)) dfs(ls(u)) ;
	out << val[u] << '\n' ;
	if(rs(u)) dfs(rs(u)) ;
}
signed main() {
#ifdef _WIN64
	freopen("testdata.in" , "r" , stdin) ;
#endif
	in >> n >> m ;
	rep(i , 1 , n) in >> a[i] ;
	rt = newnode(a[1]) ;
	t[rt] = s[rt] = inf ;
	rep(i , 2 , n) ins(i - 1 , a[i]) ;
	rep(i , 1 , m) {
		string s ;
		in >> s ;
		int x , y ;
		in >> x >> y ;
		if(s == "max") out << qrymax(x , y) << '\n' ;
		if(s == "min") out << qrymin(x , y) << '\n' ;
		if(s == "merge") _merge(x , y) ;
		if(s == "insert") ins(x , y) ;
	}
	return out.flush(), 0;
}
posted @ 2020-01-18 12:59  _Isaunoya  阅读(145)  评论(0编辑  收藏  举报