您的位置:首页 > 其它

BZOJ 1058 - [ZJOI2007]报表统计 STL splay [挖坑待填]

2014-09-09 11:07 441 查看

1058: [ZJOI2007]报表统计

Time Limit: 15 Sec Memory Limit: 162 MB

Submit: 1791 Solved: 632

[Submit][Status]

Description

小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写了一个程序,使得程序可以自动完成这些操作,但是他发现对于一些大的报表他的程序运行得很慢,你能帮助他改进程序么?

Input

第一行包含两个整数N,M,分别表示原数列的长度以及操作的次数。第二行为N个整数,为初始序列。接下来的M行每行一个操作,即“INSERT i k”,“MIN_GAP”,“MIN_SORT_GAP”中的一种(无多余空格或者空行)。

Output

对于每一个“MIN_GAP”和“MIN_SORT_GAP”命令,输出一行答案即可。

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

对于30%的数据,N ≤ 1000 , M ≤ 5000 对于100%的数据,N , M ≤500000 对于所有的数据,序列内的整数不超过5*108。

Source



[Submit][Status]

先用STL水过去的 先挖个坑 学了splay补上

对于MIN_SORT_GAP可以用set保存然后找出相邻两个求最小值然后更新

对于MIN_GAP,最开始想简单了,只考虑了插入一个数会增加两个差值,忘了考虑之前的一个差值应该去掉,所以WA了。

然后想法是把之前的所有差值和对应的相邻两个元素保存起来,但是感觉这有代码量太大,然后参考别人的,感觉自己好笨,为什么要保存相邻的两个元素?为了去掉的时候能找到啊。直接保存每个差值有多少个,然后去掉的时候相应的差值减1不就行了?。。。map保存差值的数量

#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <string>
#include <map>
#include <cmath>
#include <queue>
#include <set>

using namespace std;

//#define WIN
#ifdef WIN
typedef __int64 LL;
#define iform "%I64d"
#define oform "%I64d\n"
#define oform1 "%I64d"
#else
typedef long long LL;
#define iform "%lld"
#define oform "%lld\n"
#define oform1 "%lld"
#endif

#define S64I(a) scanf(iform, &(a))
#define P64I(a) printf(oform, (a))
#define P64I1(a) printf(oform1, (a))
#define REP(i, n) for(int (i)=0; (i)<n; (i)++)
#define REP1(i, n) for(int (i)=1; (i)<=(n); (i)++)
#define FOR(i, s, t) for(int (i)=(s); (i)<=(t); (i)++)

const int INF = 0x3f3f3f3f;
const double eps = 1e-9;
const double PI = (4.0*atan(1.0));

const int maxn = 500000 + 20;
int A[maxn];
bool vis[maxn];
int last[maxn];
set<int> S;
set<int>::iterator it;
map<int, int> cnt;
map<int, int>::iterator mit, tmit;
char str[20];

int main() {
int n, m;
int MIN_GAP, MIN_SORT_GAP = -1;

memset(vis, 0, sizeof(vis));
scanf("%d%d", &n, &m);
for(int i=1; i<=n; i++) {
scanf("%d", &A[i]);
it = S.lower_bound(A[i]);
if(it != S.end()) {
int t = abs(A[i] - *it);
if(MIN_SORT_GAP == -1 || t < MIN_SORT_GAP) MIN_SORT_GAP = t;
}
if(it != S.begin()) {
it--;
int t = abs(A[i] - *it);
if(MIN_SORT_GAP == -1 || t < MIN_SORT_GAP) MIN_SORT_GAP = t;
}
S.insert(A[i]);
if(i > 1) {
int t = abs(A[i] - A[i-1]);
cnt[t]++;
if(i == 2) MIN_GAP = t;
else if(i > 2 && t< MIN_GAP) MIN_GAP = t;
}
}
for(int i=0; i<m; i++) {
scanf("%s", str);
if(strcmp(str, "MIN_GAP") == 0) {
printf("%d\n", MIN_GAP);
} else if(strcmp(str, "MIN_SORT_GAP") == 0) {
printf("%d\n", MIN_SORT_GAP);
} else if(strcmp(str, "INSERT") == 0) {
int pos, val;
scanf("%d%d", &pos, &val);
it =  S.lower_bound(val);
if(it != S.end()) {
int t = abs(val - *it);
if(MIN_SORT_GAP == -1 || t < MIN_SORT_GAP) MIN_SORT_GAP = t;
}
if(it != S.begin()) {
it--;
int t = abs(val - *it);
if(MIN_SORT_GAP == -1 || t < MIN_SORT_GAP) MIN_SORT_GAP = t;
}
S.insert(val);
int tai = vis[pos] ? last[pos] : A[pos];
int t1 = abs(tai-val);
cnt[t1]++;
if(pos < n) {
int t2 = abs(val - A[pos+1]);
cnt[t2]++;
int t3 = abs(tai - A[pos+1]);
cnt[t3]--;
}
mit = cnt.begin();
while(mit != cnt.end() && mit->second == 0) {
tmit = mit++;
cnt.erase(tmit);
}
MIN_GAP = mit->first;
vis[pos] = 1;
last[pos] = val;
}
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: