【STL】报表统计
2012-04-18 10:11
176 查看
报表统计
【问题描述】
小Q的妈妈是一个出纳,经常需要做一些统计报表的工作。今天是妈妈的生日,小Q希望可以帮妈妈分担一些工作,作为她的生日礼物之一。经过仔细观察,小Q发现统计一张报表实际上是维护一个非负整数数列,并且进行一些查询操作。
在最开始的时候,有一个长度为N的整数序列,并且有以下三种操作:
INSERT i k | 在原数列的第i个元素后面添加一个新元素k;如果原数列的第i个元素已经添加了若干元素,则添加在这些元素的最后(见下面的例子) |
MIN_GAP | 查询相邻两个元素的之间差值(绝对值)的最小值 |
MIN_SORT_GAP | 查询所有元素中最接近的两个元素的差值(绝对值) |
例如一开始的序列为
5 | 3 | 1 |
执行操作INSERT2 9将得到:
5 | 3 | 9 | 1 |
再执行操作INSERT2 6将得到:
5 | 3 | 9 | 6 | 1 |
注意这个时候原序列的第2个元素后面已经添加了一个9,此时添加的6应加在9的后面。这个时候MIN_GAP为2,MIN_SORT_GAP为1。
于是小Q写了一个程序,使得程序可以自动完成这些操作,但是他发现对于一些大的报表他的程序运行得很慢,你能帮助他改进程序么?
【输入文件】
输入文件form.in第一行包含两个整数N,M,分别表示原数列的长度以及操作的次数。第二行为N个整数,为初始序列。
接下来的M行每行一个操作,即“INSERTi k”,“MIN_GAP”,“MIN_SORT_GAP”中的一种(无多余空格或者空行)。
【输出文件】
对于每一个“MIN_GAP”和“MIN_SORT_GAP”命令,输出一行答案即可。【样例输入】
3 55 3 1
INSERT 2 9
MIN_SORT_GAP
INSERT 2 6
MIN_GAP
MIN_SORT_GAP
【样例输出】
22
1
【数据规模】
对于30%的数据,N ≤ 1000 , M ≤ 5000对于100%的数据,N , M≤500000
对于所有的数据,序列内的整数不超过5*108。
练习STL的好题。
考虑每个数要插在原数列的某位置后面,我们把一个数列变成一个链表头集。
对于min_gap的维护:每增加一个数,则删除上一个数和下一个位置第一个数的差,再插入新数和这个位置上一个数的差还有新数和下一位置第一个数的差。
对于min_sort_gap的维护:用一个全局变量minsortgap和一棵平衡二叉树来维护。树中存储所有的元素。。每插入一个数,则在树中到刚好比他大和刚好比他小的树,更新minsortgap。
#include <cstring>
#include <string>
#include <cstdio>
#include <set>
#include <algorithm>
const int inf = 0x7f7f7f7f;
int minsortgap = inf;
std::multiset<int> storage;
std::multiset<int> mingap;
int array[500010][2];
int count[500010];
std::multiset<int>::iterator it1;
inline int ABS(int a)
{
return a>0?a:-a;
}
inline int getint()
{
int res = 0;char tmp;bool sgn = 1;
do tmp = getchar();
while (!isdigit(tmp)&&tmp!='-');
if (tmp=='-'){sgn = 0;tmp=getchar();}
do res = (res<<3)+(res<<1) + tmp-'0';
while (isdigit(tmp = getchar()));
return sgn?res:-res;
}
int main()
{
freopen("form.in","r",stdin);
freopen("form.out","w",stdout);
int n = getint();
int m = getint();
{
int tmp = getint();
storage.insert(tmp);
array[1][0] = tmp;
array[1][1] = 0;
count[1] = 0;
}
for (int i=2;i<n+1;i++)
{
int tmp = getint();
it1 = storage.lower_bound(tmp);
if (it1 != storage.end())
minsortgap = std::min(ABS(*it1-tmp),minsortgap);
if (it1 != storage.begin())
minsortgap = std::min(ABS(*(--it1)-tmp),minsortgap);
storage.insert(tmp);
mingap.insert(ABS(tmp-array[i-1][0]));
array[i][0] = tmp;
array[i][1] = 0;
count[i] = 0;
}
while (m --)
{
char op;
while ((op=getchar())-'I'&&op-'M');
if (op == 'I')
{
int i = getint();
int k = getint();
if (i < n)
{
it1 = mingap.find(ABS(array[i][count[i]]-array[i+1][0]));
if (it1 != mingap.end()) mingap.erase(it1);
}
mingap.insert(ABS(array[i][count[i]]-k));
if (i < n)
mingap.insert(ABS(array[i+1][0]-k));
it1 = storage.lower_bound(k);
if (it1 != storage.end())
minsortgap = std::min(ABS(*it1-k),minsortgap);
if (it1 != storage.begin())
minsortgap = std::min(ABS(*(--it1)-k),minsortgap);
storage.insert(k);
// array[i][0] = array[i][1];
array[i][1] = k;
count[i] = 1;
}
else
{
while ((op=getchar())-'G'&&op-'S');
if (op == 'G')
printf("%ld\n",*mingap.begin());
else
printf("%ld\n",minsortgap);
}
}
return 0;
}
相关文章推荐
- BZOJ 1058: [ZJOI2007]报表统计 STL
- BZOJ1058(ZJOI2007)报表统计--STL
- bzoj1058: [ZJOI2007]报表统计 STL
- BZOJ_1058_[ZJOI2007]报表统计_STL
- BZOJ 1058: [ZJOI2007]报表统计 STL 维护全局和局部最优值
- 【BZOJ1058】[ZJOI2007]报表统计 STL
- ★【STL】报表统计
- BZOJ1058 [ZJOI2007]报表统计 STL
- 使用C#和Excel进行报表开发(二)-操作统计图(Chart)
- 大型统计报表,数据透析表。
- net使用DotNetCharting控件生成报表统计图总结
- mysql按照天统计报表当天没有数据填0的实现代码
- 用Java在Web页面上输出统计图 统计报表
- 非常规统计报表之制作按段分组报表的新办法
- Oracle EBS 统计我们客制的报表
- C#.net使用DotNetCharting控件生成报表统计图--A
- 高级交叉报表例子程序(C#)中明细列统计数据错误改正!
- 一个统计报表sql问题
- mantis统计报表和图形报表出现乱码问题的解决方法(摘录)
- 统计报表