博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【BZOJ4864】神秘物质 [Splay]
阅读量:5231 次
发布时间:2019-06-14

本文共 3635 字,大约阅读时间需要 12 分钟。

神秘物质

Time Limit: 10 Sec  Memory Limit: 256 MB

Description

Input

  

Output

  

Sample Input

  

Sample Output

  1

  2
  1
  5

HINT

  

Main idea

  每个点有一个权值,维护一个结构,支持合并相邻两点,删除单点,加入单点,查询区间子集极差的最大值和最小值。

Solution

  首先我们可以发现,区间子集极差的最大值显然就是整个区间的最大值-区间最小值,然后区间子集极差最小值只有相邻点的才会产生贡献

  那么我们用Splay来维护这个结构即可,维护一下子树最大值、子树最小值、子树邻差最小值即可。

Code

1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 using namespace std; 9 typedef long long s64; 10 11 const int ONE = 300005; 12 const int INF = 2147483640; 13 14 int n,m; 15 int x,y,a[ONE]; 16 int root,cnt; 17 int lc[ONE],rc[ONE],fa[ONE]; 18 int size[ONE],val[ONE]; 19 int maxx[ONE],minn[ONE],del[ONE]; 20 int Ls[ONE],Rs[ONE]; 21 char ch[10]; 22 23 inline int get() 24 { 25 int res=1,Q=1; char c; 26 while( (c=getchar())<48 || c>57) 27 if(c=='-')Q=-1; 28 if(Q) res=c-48; 29 while((c=getchar())>=48 && c<=57) 30 res=res*10+c-48; 31 return res*Q; 32 } 33 34 void Up(int i) 35 { 36 size[i] = size[lc[i]] + size[rc[i]] + 1; 37 maxx[i] = minn[i] = val[i]; 38 del[i] = INF; 39 Ls[i] = Rs[i] = i; 40 if(lc[i]) 41 { 42 Ls[i] = Ls[lc[i]]; 43 maxx[i] = max(maxx[i], maxx[lc[i]]); 44 minn[i] = min(minn[i], minn[lc[i]]); 45 del[i] = min(del[i], del[lc[i]]); 46 del[i] = min(del[i], abs( val[i]-val[Rs[lc[i]]] ) ); 47 } 48 if(rc[i]) 49 { 50 Rs[i] = Rs[rc[i]]; 51 maxx[i] = max(maxx[i], maxx[rc[i]]); 52 minn[i] = min(minn[i], minn[rc[i]]); 53 del[i] = min(del[i], del[rc[i]]); 54 del[i] = min(del[i], abs( val[i]-val[Ls[rc[i]]] ) ); 55 } 56 } 57 58 void Turn(int x) 59 { 60 int y = fa[x], z = fa[y]; 61 int b = x==lc[y] ? rc[x]:lc[x]; 62 63 fa[y] = x; fa[x] = z; 64 if(b) fa[b] = y; 65 66 if(z) 67 { 68 if(y == lc[z]) lc[z] = x; 69 else rc[z] = x; 70 } 71 72 if(x==lc[y]) rc[x] = y,lc[y] = b; 73 else lc[x] = y, rc[y] = b; 74 75 Up(y); Up(x); 76 } 77 78 void Splay(int x,int pos) 79 { 80 while(fa[x] != pos) 81 { 82 if(fa[fa[x]] != pos) 83 { 84 if( (lc[fa[x]]==x) == (lc[fa[fa[x]]]==fa[x]) ) Turn(fa[x]); 85 else Turn(x); 86 } 87 Turn(x); 88 } 89 if(pos == 0) root = x; 90 } 91 92 int Build(int i,int l,int r) 93 { 94 int mid = l+r >> 1; 95 fa[mid] = i; 96 if(l <= mid-1) lc[mid] = Build(mid, l,mid-1); 97 if(mid+1 <= r) rc[mid] = Build(mid, mid+1,r); 98 Up(mid); 99 return mid;100 }101 102 int Getid(int num)103 {104 int i = root;105 while(size[lc[i]] + 1 != num)106 {107 if(size[lc[i]] + 1 < num)108 num -= size[lc[i]] + 1, i = rc[i];109 else i = lc[i];110 }111 return i;112 }113 114 void Delete(int i)115 {116 int x = Getid(i);117 Splay(x, 0);118 int L = Rs[lc[x]]; Splay(L,0);119 int R = Ls[rc[x]]; Splay(R,L);120 lc[R] = 0;121 Splay(R,0);122 }123 124 void Insert(int i,int Val)125 {126 int x = Getid(i);127 Splay(x,0);128 int R = Ls[rc[x]]; Splay(R,x);129 val[++cnt] = Val; fa[cnt] = R; lc[R] = cnt;130 Splay(cnt,0);131 }132 133 int main()134 {135 n=get(); m=get();136 for(int i=1;i<=n;i++)137 val[i+1] = get();138 val[1] = val[n+2] = INF;139 140 cnt = n+2;141 root = n+3 >> 1;142 Build(0,1,n+2);143 144 while(m--)145 {146 scanf("%s",ch+1); x=get(); y=get();147 x++;148 149 if(ch[3] == 'r')150 {151 Insert(x+1,y);152 Delete(x); Delete(x);153 }154 if(ch[3] == 's')155 Insert(x,y);156 if(ch[3] == 'x')157 {158 y++;159 x = Getid(x-1); y = Getid(y+1);160 Splay(x,0); Splay(y,x);161 printf("%d\n", maxx[lc[y]] - minn[lc[y]]);162 }163 if(ch[3] == 'n')164 {165 y++;166 x = Getid(x-1); y = Getid(y+1);167 Splay(x,0); Splay(y,x);168 printf("%d\n", del[lc[y]]);169 }170 171 }172 }
View Code

 

转载于:https://www.cnblogs.com/BearChild/p/6715453.html

你可能感兴趣的文章
Springboot使用步骤
查看>>
Spring其他注解
查看>>
Spring属性注入
查看>>
Springboot-配置文件
查看>>
Spring-自动配置
查看>>
Springboot-日志框架
查看>>
SpringBoot-静态资源映射
查看>>
SpringBoot-webjars
查看>>
SpringBoot-thymeleaf
查看>>
IDEA 调试 JAVA ConcurrentLinkedQueue
查看>>
P1908-逆序对
查看>>
P1192-台阶问题
查看>>
ACM模板——康托展开
查看>>
P1025-数的划分
查看>>
P1305-新二叉树
查看>>
LGTB 与大数
查看>>
[POI2009]KAM-Pebbles
查看>>
JavaScript对象
查看>>
bzoj 3696: 化合物
查看>>
LeetCode 28. Implement strStr()
查看>>