zoukankan      html  css  js  c++  java
  • 【BZOJ1058】[ZJOI2007]报表统计 STL

    【BZOJ1058】[ZJOI2007]报表统计

    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

    N , M ≤500000 对于所有的数据,序列内的整数不超过5*10^8。

    题解:头一次感觉STL没有平衡树好写~

    我们需要维护两个multiset m1,m2,m1维护的是整个序列中的数,m2维护的是所有相邻两个数的差值。还需要维护一个堆,维护所有相邻两个数的差值的最小值。还要维护一个变量,代表所有排序后相邻两个数的差值。

    我们发现,对于每一次操作,需要知道的只有当前位置的最后一个数和下一个位置的第一个数,所以只需要维护每个位置的第一个数和最后一个数就行了。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <set>
    #include <queue>
    using namespace std;
    const int maxn=500010;
    multiset<int> m1,m2,m3;
    multiset<int>::iterator it;
    priority_queue<int> p1;
    int n,m,p2;
    int L[maxn],R[maxn];
    char str[20];
    int abs(int x)
    {
    	return x>0?x:-x;
    }
    int rd()
    {
    	int ret=0,f=1;	char gc=getchar();
    	while(gc<'0'||gc>'9')	{if(gc=='-')f=-f;	gc=getchar();}
    	while(gc>='0'&&gc<='9')	ret=ret*10+gc-'0',gc=getchar();
    	return ret*f;
    }
    int main()
    {
    	n=rd(),m=rd(),p2=1<<30;
    	int i,j,a,b,c;
    	for(i=1;i<=n;i++)	L[i]=R[i]=rd(),m1.insert(L[i]);
    	for(i=2;i<=n;i++)
    	{
    		if(m2.find(abs(L[i]-L[i-1]))==m2.end())	p1.push(-abs(L[i]-L[i-1]));
    		m2.insert(abs(L[i]-L[i-1]));
    	}
    	for(it=m1.begin(),i=*it,++it;it!=m1.end();it++)
    		p2=min(p2,(*it)-i),i=*it;
    	for(i=1;i<=m;i++)
    	{
    		scanf("%s",str);
    		if(str[0]=='I')
    		{
    			a=rd(),b=rd();
    			if(a!=n)
    			{
    				m2.erase(m2.find(abs(L[a+1]-R[a])));
    				if(m2.find(abs(L[a+1]-b))==m2.end())	p1.push(-abs(L[a+1]-b));
    				m2.insert(abs(L[a+1]-b));
    			}
    			if(m2.find(abs(b-R[a]))==m2.end())	p1.push(-abs(b-R[a]));
    			m2.insert(abs(b-R[a]));
    			it=m1.lower_bound(b);
    			if(it!=m1.end())	p2=min(p2,(*it)-b);
    			if(it!=m1.begin())	it--,p2=min(p2,b-(*it));
    			m1.insert(b),R[a]=b;
    		}
    		if(str[4]=='G')
    		{
    			while(m2.find(-p1.top())==m2.end())	p1.pop();
    			printf("%d
    ",-p1.top());
    		}
    		if(str[4]=='S')	printf("%d
    ",p2);
    	}
    	return 0;
    }
  • 相关阅读:
    POJ 2236 Wireless Network(并查集)
    POJ 2010 Moo University
    POJ 3614 Sunscreen(贪心,区间单点匹配)
    POJ 2184 Cow Exhibition(背包)
    POJ 1631 Bridging signals(LIS的等价表述)
    POJ 3181 Dollar Dayz(递推,两个long long)
    POJ 3046 Ant Counting(递推,和号优化)
    POJ 3280 Cheapest Palindrome(区间dp)
    POJ 3616 Milking Time(dp)
    POJ 2385 Apple Catching(01背包)
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/6999989.html
Copyright © 2011-2022 走看看