BZOJ4864: [BeiJing 2017 Wc]神秘物质(Splay)

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

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 }
原文地址:https://www.cnblogs.com/blog-Dr-J/p/10116161.html