【STL】报表统计

报表统计

【问题描述】

       小Q的妈妈是一个出纳,经常需要做一些统计报表的工作。今天是妈妈的生日,小Q希望可以帮妈妈分担一些工作,作为她的生日礼物之一。

       经过仔细观察,小Q发现统计一张报表实际上是维护一个非负整数数列,并且进行一些查询操作。

在最开始的时候,有一个长度为N的整数序列,并且有以下三种操作:

             

INSERT i k

在原数列的第i个元素后面添加一个新元素k;如果原数列的第i个元素已经添加了若干元素,则添加在这些元素的最后(见下面的例子)

MIN_GAP

查询相邻两个元素的之间差值(绝对值)的最小值

MIN_SORT_GAP

查询所有元素中最接近的两个元素的差值(绝对值)

      

       例如一开始的序列为

5

3

1

 

执行操作INSERT2  9将得到:

5

3

9

1

此时MIN_GAP为2,MIN_SORT_GAP为2。

 

再执行操作INSERT2  6将得到:

5

3

9

6

1

 

注意这个时候原序列的第2个元素后面已经添加了一个9,此时添加的6应加在9的后面。这个时候MIN_GAP为2,MIN_SORT_GAP为1。

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

【输入文件】

       输入文件form.in第一行包含两个整数NM,分别表示原数列的长度以及操作的次数。

       第二行为N个整数,为初始序列。

       接下来的M行每行一个操作,即“INSERTi k”,“MIN_GAP”,“MIN_SORT_GAP”中的一种(无多余空格或者空行)。

【输出文件】

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

【样例输入】

       3 5

       5 3 1

       INSERT 2 9

       MIN_SORT_GAP

       INSERT 2 6

       MIN_GAP

       MIN_SORT_GAP

【样例输出】

       2

       2

       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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STL(Standard Template Library)是C++的一个标准模板库,其中包含了一系列的容器、算法和迭代器等。 要遍历并统计重复数字,可以使用STL中的容器和算法来实现。以下是一个简单的实现示例: 1. 首先,我们可以使用一个vector容器来存储数字序列,其中包含了重复的数字。 2. 然后,使用STL中的count函数来统计某个数值在容器中出现的次数。count函数接受两个参数,第一个参数是容器的起始迭代器,第二个参数是容器的结束迭代器。 3. 最后,我们可以遍历整个容器,对每个数字使用count函数来统计其在容器中出现的次数,并将结果保存到一个统计变量中。 下面是一段示例代码,说明了如何使用STL来遍历并统计重复数字: ```cpp #include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> numbers{1, 2, 3, 4, 5, 2, 3, 4, 2, 4}; // 数字序列,包含了重复数字 int targetNumber = 2; // 要统计的数字 int count = std::count(numbers.begin(), numbers.end(), targetNumber); // 使用count函数统计重复次数 std::cout << "数字 " << targetNumber << " 在序列中重复了 " << count << " 次。" << std::endl; return 0; } ``` 在上述示例中,我们将数字序列存储在vector容器numbers中,并定义了一个要统计的数字targetNumber为2。然后,使用std::count函数遍历numbers容器,统计数字2在序列中的重复次数,并将结果保存在count变量中。最后,打印出统计结果。 该示例的运行结果是:数字2在序列中重复了3次。 通过STL的容器和算法,我们可以方便地进行数字序列的遍历和统计操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值