标签:merge log 数据结构 char 合并 mil void 一段 content
原文地址:http://www.cnblogs.com/GXZlegend/p/6801631.html
题目描述
输入
输出
样例输入
4 3
5 8 10 2
max 1 3
min 1 3
max 2 4
样例输出
5
2
8
题解
Splay
支持插入删除修改查询操作的数据结构当然是Splay
而且有:极差最大值必为整个区间的极差,极差最小值必为区间内两个相邻数的差的绝对值。
所以Splay应维护:子树最大值、子树最小值、子树最小极差。
前两个操作很水,最后一个操作还需要用到左子树中最后一个数、右子树中第一个数,一起维护一下就好了。
1A~ 很开心~
#include <cstdio> #include <cstring> #include <algorithm> #define N 200010 using namespace std; int fa[N] , c[2][N] , si[N] , w[N] , maxn[N] , minn[N] , dl[N] , dr[N] , ms[N] , root; char str[10]; int abs(int x) { return x > 0 ? x : -x; } void pushup(int x) { si[x] = si[c[0][x]] + si[c[1][x]] + 1; dl[x] = c[0][x] ? dl[c[0][x]] : x; dr[x] = c[1][x] ? dr[c[1][x]] : x; maxn[x] = max(w[x] , max(maxn[c[0][x]] , maxn[c[1][x]])); minn[x] = min(w[x] , min(minn[c[0][x]] , minn[c[1][x]])); ms[x] = min(ms[c[0][x]] , ms[c[1][x]]); if(c[0][x]) ms[x] = min(ms[x] , abs(w[x] - w[dr[c[0][x]]])); if(c[1][x]) ms[x] = min(ms[x] , abs(w[x] - w[dl[c[1][x]]])); } void build(int l , int r , int f) { if(l > r) return; int mid = (l + r) >> 1; build(l , mid - 1 , mid) , build(mid + 1 , r , mid); fa[mid] = f , c[mid > f][f] = mid; pushup(mid); } void rotate(int &k , int x) { int y = fa[x] , z = fa[y] , l = (c[1][y] == x) , r = l ^ 1; if(y == k) k = x; else c[c[1][z] == y][z] = x; fa[x] = z , fa[y] = x , fa[c[r][x]] = y , c[l][y] = c[r][x] , c[r][x] = y; pushup(y) , pushup(x); } void splay(int &k , int x) { while(x != k) { int y = fa[x] , z = fa[y]; if(y != k) { if((c[0][z] == y) ^ (c[0][y] == x)) rotate(k , x); else rotate(k , y); } rotate(k , x); } } int find(int k , int x) { if(x <= si[c[0][k]]) return find(c[0][k] , x); else if(x > si[c[0][k]] + 1) return find(c[1][k] , x - si[c[0][k]] - 1); else return k; } int split(int l , int r) { int a = find(root , l - 1) , b = find(root , r + 1); splay(root , a) , splay(c[1][root] , b); return c[0][c[1][root]]; } int main() { int n , m , i , x , y , t , tot; scanf("%d%d" , &n , &m) , tot = n + 2; for(i = 2 ; i <= n + 1 ; i ++ ) scanf("%d" , &w[i]); maxn[0] = 0 , minn[0] = ms[0] = 0x3fffffff; build(1 , n + 2 , 0) , root = (n + 3) >> 1; while(m -- ) { scanf("%s%d%d" , str , &x , &y); switch(str[1]) { case ‘e‘: t = split(x + 1 , x + 2) , c[0][t] = c[1][t] = 0 , w[t] = y , pushup(t) , pushup(c[1][root]) , pushup(root); break; case ‘n‘: split(x + 2 , x + 1) , c[0][c[1][root]] = ++tot , w[tot] = y , fa[tot] = c[1][root] , pushup(tot) , pushup(c[1][root]) , pushup(root); break; case ‘a‘: t = split(x + 1 , y + 1) , printf("%d\n" , maxn[t] - minn[t]); break; default: printf("%d\n" , ms[split(x + 1 , y + 1)]); } } return 0; }
【bzoj4864】[BeiJing 2017 Wc]神秘物质 Splay
标签:merge log 数据结构 char 合并 mil void 一段 content
原文地址:http://www.cnblogs.com/GXZlegend/p/6801631.html