Describe
题目链接
小 Q 的妈妈是一个出纳,经常需要做一些统计报表的工作。今天是妈妈的生日,小 Q 希望可以帮妈妈分担一些工作,作为她的生日礼物之一。
经过仔细观察,小 Q 发现统计一张报表实际上是维护一个非负整数数列,并且进行一些查询操作。
在最开始的时候,有一个长度为$ n$的整数序列$a$,并且有以下三种操作:
INSERT i k
:在原数列的第$ i$个元素后面添加一个新元素$ k$;如果原数列的第$ i$个元素已经添加了若干元素,则添加在这些元素的最后(见样例说明)。
MIN_GAP
:查询相邻两个元素的之间差值(绝对值)的最小值。
MIN_SORT_GAP
:查询所有元素中最接近的两个元素的差值(绝对值)。
于是小 Q 写了一个程序,使得程序可以自动完成这些操作,但是他发现对于一些大的报表他的程序运行得很慢,你能帮助他改进程序么?
Solution
开两个multiset即可。
一个存放所有元素的最小差值,一个存放相邻元素的最小差值。
每次插入一个数字可以处理下前驱和后继即可。
细节详见代码。
P.S.千万不要作死用vector.
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| #include<bits/stdc++.h> #define It multiset<int>::iterator #define inf 2000000010 using namespace std; inline int read(){ int res=0,f=1;char ch=getchar(); while(ch<'0'ch>'9'){if(ch=='-') f=-1;ch=getchar();} while(ch>='0'&&ch<='9') res=res*10+ch-'0',ch=getchar(); return res*f; } inline void write(int x){ if(x<0) x=-x,putchar('-'); if(x<10) putchar(x+'0'); else write(x/10),putchar(x%10+'0'); } int n,m,Min=inf,las,nxt,tmp,a[500010],b[500010]; multiset<int> v,d; char c; int main(){ n=read();m=read(); for(int i=1;i<=n;i++) a[i]=b[i]=read(),v.insert(a[i]); v.insert(inf);v.insert(-inf); for(int i:v) Min=min(Min,abs(i-las)),las=i; for(int i=2;i<=n;i++) d.insert(abs(a[i]-a[i-1])); for(int x,y,i=1;i<=m;i++){ c=getchar();while(c!='M'&&c!='I'&&c!='N'&&c!='_'&&c!='S'&&c!='O'&&c!='T'&&c!='G'&&c!='A'&&c!='P'&&c!='E'&&c!='R') c=getchar(); if(c=='I'){ while(c=='M'c=='I'c=='N'c=='_'c=='S'c=='O'c=='T'c=='G'c=='A'c=='P'c=='E'c=='R') c=getchar(); x=read();y=read(); las=b[x]; if(x!=n){ nxt=a[x+1]; tmp=abs(las-nxt); d.erase(d.find(tmp)); d.insert(abs(y-nxt)); } d.insert(abs(y-las)); b[x]=y; It pos=v.lower_bound(y); Min=min(Min,abs(y-*pos)); --pos; Min=min(Min,abs(y-*pos)); v.insert(y); }else{ c=getchar();c=getchar();c=getchar();c=getchar(); if(c=='G'){ while(c=='M'c=='I'c=='N'c=='_'c=='S'c=='O'c=='T'c=='G'c=='A'c=='P'c=='E'c=='R') c=getchar(); write(*d.begin());putchar('\n'); }else{ while(c=='M'c=='I'c=='N'c=='_'c=='S'c=='O'c=='T'c=='G'c=='A'c=='P'c=='E'c=='R') c=getchar(); write(Min);putchar('\n'); } } } }
|