zoukankan      html  css  js  c++  java
  • BZOJ 1058: [ZJOI2007]报表统计

    1058: [ZJOI2007]报表统计

    Time Limit: 15 Sec  Memory Limit: 162 MB

    Submit: 3844  Solved: 1309

    [Submit][Status][Discuss]

    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。

    题解

    用两个集合,一个放所有的数,每次更新MIN_SORT_GAP就将数放进集合然后与前一个数和后一个数做差更新答案,另一个集合放所有的相邻数的差值,用s[i]和e[i]表示第i个位置开始和结束的数是多少,每次向i位置后插入x,就先弹出e[i]与s[i+1]的差值,再插入e[i]与x的差值和x与s[i+1]的差值并更新e[i],答案输出集合第一个数即可。

    代码

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<iostream>
    #include<set>
    #define ite multiset<int>::iterator
    using namespace std;
    const int N=500005,inf=0x3f3f3f3f;
    int n,m,ans=inf;
    int a[N],s[N],e[N];
    multiset<int>num,c;
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++){
    		scanf("%d",&a[i]);
    		s[i]=e[i]=a[i];
    		num.insert(a[i]);
    		if(i>1)c.insert(abs(a[i]-a[i-1]));
    	}
    	ite l=num.begin(),r=num.begin();
    	r++;
    	while(r!=num.end()){
    		ans=min(ans,*r-*l);
    		l++,r++;
    	}
    	ite t;
    	int i,k;
    	char ch[20];
    	while(m--){
    		scanf("%s",ch);
    		if(ch[0]=='I'){
    			scanf("%d%d",&i,&k);
    			t=num.insert(k);
    			if(t!=num.begin()){
    				t--;
    				ans=min(ans,k-*t);
    				t++;
    			}
    			t++;
    			if(t!=num.end())ans=min(ans,*t-k);
    			t--;
    			t=c.find(abs(s[i+1]-e[i]));
    			c.erase(t);
    			c.insert(abs(k-e[i]));
    			c.insert(abs(s[i+1]-k));
    			e[i]=k;
    		}
    		else if(ch[4]=='G')printf("%d
    ",*c.begin());
    		else printf("%d
    ",ans);
    	}
    	return 0;
    }
  • 相关阅读:
    C++ 将对象写入文件 并读取
    IronPython fail to add reference to WebDriver.dll
    How to Capture and Decrypt Lync Server 2010 TLS Traffic Using Microsoft Tools
    .net code injection
    数学系学生应该知道的十个学术网站
    Difference Between Currency Swap and FX Swap
    Swift开源parser
    谈谈我对证券公司一些部门的理解(前、中、后台)[z]
    JDK8记FullGC时候Metaspace内存不会被垃圾回收
    JVM源码分析之JDK8下的僵尸(无法回收)类加载器[z]
  • 原文地址:https://www.cnblogs.com/chezhongyang/p/7745873.html
Copyright © 2011-2022 走看看