zoukankan      html  css  js  c++  java
  • bzoj 1058: [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写了一个程序,使
    得程序可以自动完成这些操作,但是他发现对于一些大的报表他的程序运行得很慢,你能帮助他改进程序么?

    solution

    正解:堆+平衡树
    又堕落了QwQ,说好的平衡树呢?
    对于第一个操作,我们链表维护一下即可
    对于第二个询问,我们维护一个堆,我们每加入一个元素就把与前后差值加入堆中,堆中记录后继,便于删除.
    对于第三个询问,答案单调不升,直接平衡树维护全局变量,插入时取min即可

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    #include <cmath>
    #include <set>
    #define RG register
    #define il inline
    #define iter iterator
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    using namespace std;
    typedef long long ll;
    const int N=1000005,inf=2e9;
    int n,m,nxt[N],cnt=0,pre[N],val[N],last[N],b[N];
    char S[41];
    struct node{
    	int x,y,val;
    	bool operator <(const node &pr)const{return val>pr.val;}
    };
    priority_queue<node>q;
    multiset<int>G;
    multiset<int>::iter it;
    void work()
    {
    	int x,y,z,ans=inf;node k;
    	scanf("%d%d",&n,&m);cnt=n;
    	for(int i=1;i<=n;i++){
    		scanf("%d",&val[i]);b[i]=val[i];
    		last[i]=i;pre[i]=i-1;nxt[i]=i+1;
    		if(i!=1)q.push((node){i-1,i,abs(val[i]-val[i-1])});
    		G.insert(val[i]);
    	}
    	sort(b+1,b+n+1);
    	for(int i=2;i<=n;i++)ans=min(ans,b[i]-b[i-1]);
    	G.insert(-inf);G.insert(inf);
    	while(m--){
    		scanf("%s",S);
    		if(S[0]=='I'){
    			scanf("%d%d",&x,&z);
    			y=last[x];
    			cnt++;val[cnt]=z;
    			if(x<n)pre[x+1]=cnt,nxt[cnt]=x+1;
    			last[x]=cnt;nxt[y]=cnt;pre[cnt]=y;
    
    			q.push((node){y,cnt,abs(val[y]-z)});
    			if(x<n)q.push((node){cnt,x+1,abs(val[x+1]-z)});
    
    			it=G.lower_bound(z);
    			if(*it!=-inf){
    				ans=min(ans,abs(*it-z));
    				--it;
    				if(*it!=-inf)ans=min(ans,abs(*it-z));
    			}
    			it=G.upper_bound(z);
    			if(*it!=inf)ans=min(ans,abs(*it-z));
    			G.insert(z);
    		}
    		else if(S[4]=='G'){
    			while(!q.empty()){
    				k=q.top();
    				if(nxt[k.x]!=k.y)q.pop();
    				else {printf("%d
    ",k.val);break;}
    			}
    		}
    		else printf("%d
    ",ans);
    	}
    }
    
    int main()
    {
    	freopen("pp.in","r",stdin);
    	freopen("pp.out","w",stdout);
    	work();
    	return 0;
    }
    
    
  • 相关阅读:
    leetcode Remove Linked List Elements
    leetcode Word Pattern
    leetcode Isomorphic Strings
    leetcode Valid Parentheses
    leetcode Remove Nth Node From End of List
    leetcode Contains Duplicate II
    leetcode Rectangle Area
    leetcode Length of Last Word
    leetcode Valid Sudoku
    leetcode Reverse Bits
  • 原文地址:https://www.cnblogs.com/Yuzao/p/8040437.html
Copyright © 2011-2022 走看看