bzoj 1058【zjoi 2007】レポート統計
3438 ワード
1058:[ZJOI 2007]レポート統計
Time Limit: 15 Sec
Memory Limit: 162 MB
Submit: 2384
Solved: 824
[ Submit][ Status][ Discuss]
Description
Qさんのお母さんは出納で、よく統計報告書の仕事をしなければなりません.今日は母の誕生日で、Qさんは母の誕生日のプレゼントの一つとして、仕事を分担してほしいと思っています.よく観察すると、小Qは、統計レポートが実際には負の数の可能性のある整数数列を維持し、いくつかのクエリー操作を行うことを発見した.最初はNの長さの整数シーケンスがあり、INSERT i kは元の数列のi番目の要素の後ろに新しい要素kを追加する.元の列のi番目の要素にいくつかの要素が追加されている場合、これらの要素の最後に追加されます(次の例を参照).MIN_GAPクエリ隣接する2つの要素間の差分値(絶対値)の最小値MIN_SORT_GAPは、すべての要素の中で最も近い2つの要素の差分値(絶対値)をクエリします.たとえば、最初のシーケンスが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さんはプログラムを書いて、プログラムが自動的にこれらの操作を完成させることができますが、彼はいくつかの大きなレポートに対して彼のプログラムが遅く実行されていることを発見しました.あなたは彼のプログラムを改善することができますか?
Input
1行目は2つの整数N,Mを含み,それぞれ原数列の長さと動作回数を表す.第2の動作N個の整数は、初期シーケンスである.次のM行は、「INSERT i k」、「MIN_GAP」、「MIN_SORT_GAP」のいずれか(余分なスペースや空行がない)の行ごとに動作する.
Output
「MIN_GAP」コマンドと「MIN_SORT_GAP」コマンドごとに、1行の答えを出力します.
Sample Input
3 5 5 3 1 INSERT 2 9 MIN_SORT_GAP INSERT 2 6 MIN_GAP MIN_SORT_GAP
Sample Output
2 2 1
HINT
100%のデータに対して、N、M≦500000はすべてのデータに対して、シーケンス内の整数は5*10^8を超えない.
Source
STLにおけるsetとmapテンプレートの応用
注意:setが挿入した要素は同じではありません.multisetは同じで、multisetはxを削除するときにxに等しいすべての要素を削除したのと同じです.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<map>
#include<set>
#define F(i,j,n) for(int i=j;i<=n;i++)
#define D(i,j,n) for(int i=j;i>=n;i--)
#define LL long long
#define pa pair<int,int>
#define INF 1000000005
#define MAXN 500005
using namespace std;
int ans=INF,x,y,tmp,n,m,s[MAXN],t[MAXN];
char ch[12];
set<int>a,b;
map<int,int>mp;
inline int read()
{
int ret=0,flag=1;
char ch=getchar();
while (ch<'0'||ch>'9')
{
if (ch=='-') flag=-1;
ch=getchar();
}
while (ch>='0'&&ch<='9')
{
ret=ret*10+ch-'0';
ch=getchar();
}
return ret*flag;
}
void insa(int x)
{
mp[x]++;
if (mp[x]==1) a.insert(x);
}
void insb(int x)
{
int l=*(--b.lower_bound(x)),r=*b.lower_bound(x);
ans=min(ans,min(x-l,r-x));
b.insert(x);
}
int main()
{
n=read();m=read();
b.insert(INF);b.insert(-INF);
F(i,1,n)
{
s[i]=t[i]=read();
insb(s[i]);
}
F(i,2,n) insa(abs(s[i]-s[i-1]));
F(i,1,m)
{
scanf("%s",ch);
if (ch[0]=='I')
{
x=read();y=read();
if (x!=n)
{
tmp=abs(t[x]-s[x+1]);
mp[tmp]--;
if (!mp[tmp]) a.erase(tmp);
insa(abs(s[x+1]-y));
}
insa(abs(t[x]-y));
t[x]=y;
insb(y);
}
else if (ch[4]=='S') printf("%d
",ans);
else printf("%d
",*a.lower_bound(0));
}
return 0;
}