神秘物质
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<iostream> 2 #include<string> 3 #include<algorithm> 4 #include<cstdio> 5 #include<cstring> 6 #include<cstdlib> 7 #include<cmath> 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 }
时间: 2024-10-06 20:15:34