Description
21ZZ 年,冬。
小诚退休以后, 不知为何重新燃起了对物理学的兴趣。 他从研究所借了些实验仪器,整天研究各种微观粒子。这
一天, 小诚刚从研究所得到了一块奇异的陨石样本, 便迫不及待地开始观测。 在精密仪器的视野下,构成陨石
的每个原子都无比清晰。 小诚发现, 这些原子排成若干列, 每一列的结构具有高度相似性。于是,他决定对单
独一列原子进行测量和测试。被选中的这列共有 N 个顺序排列的原子。 最初, 第 i 个原子具有能量 Ei。 随着
时间推移和人为测试, 这列原子在观测上会产生两种变化:
merge x e 当前第 x 个原子和第 x+1 个原子合并,得到能量为 e 的新原子;
insert x e 在当前第 x 个原子和第 x+1 个原子之间插入一个能量为 e 的新原子。
对于一列原子,小诚关心的是相邻一段中能量最大和能量最小的两个原子的能量差值,
称为区间极差。 因此, 除了观测变化外,小诚还要经常统计这列原子的两类数据:
max x y 当前第 x 到第 y 个原子之间的任意子区间中区间极差的最大值;
min x y 当前第 x 到第 y 个原子之间的任意子区间中区间极差的最小值。
其中, 子区间指的是长度至少是 2 的子区间。
小诚坚信这项研究可以获得诺贝尔物理学奖。为了让小诚早日了结心愿,你能否帮助他实现上述的观测和测量呢?
Input
第一行, 两个整数 N, M, 分别表示最初的原子数目和事件总数。
第二行, N 个整数 E1, E2, …, EN, 由空格隔开。依次表示每个原子的能量。
接下来 M 行, 每行为一个字符串和两个整数, 描述一次事件,格式见题目描述。
N<=100,000,M<=100,000
1 ≤ e, Ei ≤ 109。 设 N’ 为当前时刻原子数目。
对于 merge 类事件, 1 ≤ x ≤ N’-1;
对于 insert 类事件, 1 ≤ x ≤ N’;
对于 max 和 min 类事件, 1 ≤ x < y ≤ N’。
任何时刻,保证 N’ ≥ 2。
Output
输出若干行, 按顺序依次表示每次 max 和 min 类事件的测量结果。
Sample Input
4 3
5 8 10 2
max 1 3
min 1 3
max 2 4
5 8 10 2
max 1 3
min 1 3
max 2 4
Sample Output
5 2 8
解题思路:
Splay维护插入,删除,区间统计答案。
极差最大值为区间最值差,最小值为相邻元素之差。
然后愉快地AC
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define lll tr[spc].ch[0] 5 #define rrr tr[spc].ch[1] 6 #define ls ch[0] 7 #define rs ch[1] 8 const int N=1000000; 9 struct trnt{ 10 int ch[2]; 11 int fa; 12 int E; 13 int wgt; 14 int maxval; 15 int minval; 16 int abst; 17 int minab; 18 }tr[N]; 19 int siz; 20 int root; 21 int n,m; 22 int energy[N]; 23 char cmd[30]; 24 bool whc(int spc) 25 { 26 return tr[tr[spc].fa].rs==spc; 27 } 28 void pushup(int spc) 29 { 30 tr[spc].wgt=1; 31 tr[spc].maxval=tr[spc].minval=tr[spc].E; 32 tr[spc].minab=tr[spc].abst; 33 if(lll) 34 { 35 tr[spc].wgt+=tr[lll].wgt; 36 tr[spc].maxval=std::max(tr[spc].maxval,tr[lll].maxval); 37 tr[spc].minval=std::min(tr[spc].minval,tr[lll].minval); 38 tr[spc].minab=std::min(tr[spc].minab,tr[lll].minab); 39 } 40 if(rrr) 41 { 42 tr[spc].wgt+=tr[rrr].wgt; 43 tr[spc].maxval=std::max(tr[spc].maxval,tr[rrr].maxval); 44 tr[spc].minval=std::min(tr[spc].minval,tr[rrr].minval); 45 tr[spc].minab=std::min(tr[spc].minab,tr[rrr].minab); 46 } 47 return ; 48 } 49 void rotate(int spc) 50 { 51 int f=tr[spc].fa; 52 bool k=whc(spc); 53 tr[f].ch[k]=tr[spc].ch[!k]; 54 tr[spc].ch[!k]=f; 55 tr[tr[f].fa].ch[whc(f)]=spc; 56 tr[spc].fa=tr[f].fa; 57 tr[f].fa=spc; 58 tr[tr[f].ch[k]].fa=f; 59 pushup(f); 60 pushup(spc); 61 return ; 62 } 63 void splay(int spc,int f) 64 { 65 while(tr[spc].fa!=f) 66 { 67 int ft=tr[spc].fa; 68 if(tr[ft].fa==f) 69 { 70 rotate(spc); 71 break; 72 } 73 if(whc(spc)^whc(ft)) 74 rotate(spc); 75 else 76 rotate(ft); 77 rotate(spc); 78 } 79 if(!f) 80 root=spc; 81 return ; 82 } 83 void Build(int l,int r,int &spc,int f) 84 { 85 if(l>r) 86 return ; 87 int mid=(l+r)>>1; 88 spc=++siz; 89 tr[spc].fa=f; 90 tr[spc].E=energy[mid]; 91 tr[spc].abst=std::abs(energy[mid]-energy[mid+1]); 92 Build(l,mid-1,lll,spc); 93 Build(mid+1,r,rrr,spc); 94 pushup(spc); 95 return ; 96 } 97 int plc(int spc,int v) 98 { 99 if(tr[lll].wgt>=v) 100 return plc(lll,v); 101 if(tr[lll].wgt+1==v) 102 return spc; 103 return plc(rrr,v-tr[lll].wgt-1); 104 } 105 int main() 106 { 107 scanf("%d%d",&n,&m); 108 for(int i=1;i<=n;i++) 109 scanf("%d",&energy[i]); 110 Build(0,n+1,root,0); 111 while(m--) 112 { 113 int x,y; 114 scanf("%s",cmd+1); 115 scanf("%d%d",&x,&y); 116 if(cmd[1]=='i') 117 { 118 int spc1=plc(root,x+1); 119 int spc2=plc(root,x+2); 120 int spc=++siz; 121 splay(spc1,0); 122 splay(spc2,root); 123 tr[spc1].abst=std::abs(tr[spc1].E-y); 124 tr[spc].abst=std::abs(tr[spc2].E-y); 125 tr[spc].fa=spc2; 126 tr[spc].E=y; 127 tr[spc2].ls=spc; 128 pushup(spc); 129 pushup(spc2); 130 pushup(root); 131 }else if(cmd[2]=='e') 132 { 133 int spc1=plc(root,x),spc2=plc(root,x+3); 134 splay(spc1,0); 135 splay(spc2,root); 136 tr[spc1].abst=std::abs(y-tr[spc1].E); 137 int spc=++siz; 138 tr[spc].fa=tr[root].rs; 139 tr[spc].E=y; 140 tr[spc].abst=std::abs(y-tr[spc2].E); 141 tr[tr[root].rs].ls=spc; 142 pushup(spc); 143 pushup(spc2); 144 pushup(root); 145 }else if(cmd[2]=='i') 146 { 147 int spc1=plc(root,x),spc2=plc(root,y+1); 148 splay(spc1,0); 149 splay(spc2,root); 150 int ans=tr[tr[tr[root].rs].ls].minab; 151 printf("%d ",ans); 152 }else{ 153 int spc1=plc(root,x),spc2=plc(root,y+2); 154 splay(spc1,0); 155 splay(spc2,root); 156 int ans=tr[tr[tr[root].rs].ls].maxval-tr[tr[tr[root].rs].ls].minval; 157 printf("%d ",tr[tr[tr[root].rs].ls].maxval-tr[tr[tr[root].rs].ls].minval); 158 } 159 } 160 return 0; 161 }