题意:小Q的妈妈是一个出纳,经常需要做一些统计报表的工作。今天是妈妈的生日,小Q希望可以帮妈妈分担一些工作,作为她的生日礼物之一。
经过仔细观察,小Q发现统计一张报表实际上是维护一个非负整数数列,并且进行一些查询操作。
在最开始的时候,有一个长度为N的整数序列,并且有以下三种操作:
INSERT i k 在原数列的第i个元素后面添加一个新元素k;如果原数列的第i个元素已经添加了若干元素,则添加在这些元素的最后(见下面的例子)
MIN_GAP 查询相邻两个元素的之间差值(绝对值)的最小值
MIN_SORT_GAP 查询所有元素中最接近的两个元素的差值(绝对值)
例如一开始的序列为
5 3 1
执行操作INSERT 2 9将得到:
5 3 9 1
此时MIN_GAP为2,MIN_SORT_GAP为2。
再执行操作INSERT 2 6将得到:
5 3 9 6 1
注意这个时候原序列的第2个元素后面已经添加了一个9,此时添加的6应加在9的后面。这个时候MIN_GAP为2,MIN_SORT_GAP为1。
于是小Q写了一个程序,使得程序可以自动完成这些操作,但是他发现对于一些大的报表他的程序运行得很慢,你能帮助他改进程序么?
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
开个vector表示某一位之后插的数,再开两个map(multiset也行)来维护所需两个答案就好了
#pragma GCC optimize(3,"inline","Ofast")
#include<bits/stdc++.h>
#define iter map<int,int>::iterator
using namespace std;
const int N=5e5+10;
void read(int &x)
{
char c=getchar();x=0;int r=0;
while(!isdigit(c))
{
if(c=='-')r=1;
c=getchar();
}
while(isdigit(c))x=x*10+c-48,c=getchar();
if(r)x=-x;
}
map<int,int>vis,viss;
vector<int>mp[N];
int n,m,a[N],res=2e9;
void gx(int x)
{
iter bf;
bf=viss.lower_bound(x);
if(bf!=viss.end())res=min(res,abs(bf->first-x));
if(bf!=viss.begin())--bf,res=min(res,abs(x-bf->first));
}
int main()
{
int nw,bf,ps,tmp;char s[20];iter tp;
read(n),read(m);
for(int i=1;i<=n;i++)
{
read(nw);
mp[i].push_back(nw);
if(i>1)vis[abs(nw-mp[i-1][0])]++;
gx(nw),viss[nw]++;
}
for(int i=1;i<=m;i++)
{
scanf("%s",s);
if(s[0]=='I')
{
read(ps),read(nw);
gx(nw);
if(ps!=n)
{
vis[tmp=abs(mp[ps+1][0]-mp[ps][mp[ps].size()-1])]--;
if(!vis[tmp])vis.erase(tmp);
vis[abs(mp[ps][mp[ps].size()-1]-nw)]++;
vis[abs(mp[ps+1][0]-nw)]++;
mp[ps].push_back(nw),viss[nw]++;
}
else vis[abs(mp[ps][mp[ps].size()-1]-nw)]++,viss[nw]++,mp[ps].push_back(nw);
}
else if(s[4]=='G')
{
tp=vis.begin();
printf("%d\n",tp->first);
}
else printf("%d\n",res);
}
}