很练数据结构的一道题,考试写到一半写炸了,最后交了30分的暴力。然后调了一下午。。。
相邻元素:用线段树维护最小值,每次插入时插入abs(此元素和两个相邻元素的差),
删除或覆盖abs(原来相邻元素的差),每次查询直接找整棵线段树的最小值。注意用一个数组记录一下上一次删这个位置时的位置
所有元素:用平衡树维护前驱、后继,用min(abs(前驱-此元素),abs(后继-此元素))更新ans。
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
struct node
{
int l,r;
int sum;
};
node b[4000100];
struct treap
{
int l,r,rnd;
int v;
treap(){v=0x7fffffff;}
}tree[4000100];
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<3)+(x<<1)+ch-'0';
ch=getchar();
}
return x*f;
}
int n,m,x,y;
int a,c,ans=0x7fffffff;
vector<int> jia[500005];
string s;
int root,ying[500005],tmp,size,jishu=0;
void build(int left,int right,int i)
{
int mid;
b[i].l=left;
b[i].r=right;
if(left==right)
{
b[i].sum=0x7fffffff;
return ;
}
mid=(left+right)/2;
build(left,mid,2*i);
build(mid+1,right,2*i+1);
b[i].sum=min(b[2*i].sum,b[2*i+1].sum);
}
void add(int j,int num,int i)
{
if(b[i].l==b[i].r)
{
b[i].sum=num;
return ;
}
else
{
b[i].sum=num;
if(j<=b[2*i].r)
add(j,num,2*i);
else
add(j,num,2*i+1);
}
b[i].sum=min(b[2*i].sum,b[2*i+1].sum);
}
int query(int left,int right,int i)
{
int mid;
if(b[i].l==left&&b[i].r==right)
return b[i].sum;
mid=(b[i].l+b[i].r)/2;
if(right<=mid)
return query(left,right,2*i);
else if(left>mid)
return query(left,right,2*i+1);
else
return min(query(left,mid,2*i),query(mid+1,right,2*i+1));
}
void rturn(int &k)
{
int t=tree[k].l;
tree[k].l=tree[t].r;
tree[t].r=k;
k=t;
}
void lturn(int &k)
{
int t=tree[k].r;
tree[k].r=tree[t].l;
tree[t].l=k;
k=t;
}
void insert(int &k,int x)
{
if(k==0)
{
size++;
k=size;
tree[k].v=x;
tree[k].rnd=rand();
return ;
}
else
{
if(tree[k].v<x)
{
insert(tree[k].r,x);
if(tree[tree[k].r].rnd<tree[k].rnd)
lturn(k);
}
else
{
insert(tree[k].l,x);
if(tree[tree[k].l].rnd<tree[k].rnd)
rturn(k);
}
}
}
void query_pro(int k,int x)
{
if(k==0)
return ;
if(x>=tree[k].v)
{
tmp=k;
query_pro(tree[k].r,x);
}
else
query_pro(tree[k].l,x);
}
void query_sub(int k,int x)
{
if(k==0)
return ;
if(x<=tree[k].v)
{
tmp=k;
query_sub(tree[k].l,x);
}
else
query_sub(tree[k].r,x);
}
int main()
{
freopen("form.in","r",stdin);
freopen("form.out","w",stdout);
n=read();m=read();
build(1,n+m,1);
for(int i=1;i<=n;++i)
{
a=read();
jia[i].push_back(a);
tmp=0;
query_pro(root,a);
ans=min(ans,abs(tree[tmp].v-a));
tmp=0;
query_sub(root,a);
ans=min(ans,abs(tree[tmp].v-a));
insert(root,a);
add(i-1,abs(a-c),1);
c=a;
}
for(int i=1;i<=m;++i)
{
cin>>s;
if(s[0]=='I')
{
x=read();y=read();
tmp=0;
query_pro(root,y);
ans=min(ans,abs(tree[tmp].v-y));
tmp=0;
query_sub(root,y);
ans=min(ans,abs(tree[tmp].v-y));
insert(root,y);
if(jia[x].size()==1)
ying[x]=x;
if(x!=n)
{
add(ying[x],abs(y-jia[x][jia[x].size()-1]),1);
jishu++;
add(n+jishu-1,abs(y-jia[x+1][0]),1);
ying[x]=n+jishu-1;
jia[x].push_back(y);
}
else
{
add(ying[x],abs(y-jia[x][jia[x].size()-1]),1);
jia[x].push_back(y);
}
}
if(s[4]=='S')
printf("%d\n",ans);
if(s[4]=='G')
{
int e=query(1,n+m,1);
printf("%d\n",e);
}
}
return 0;
}