zoukankan      html  css  js  c++  java
  • [补档][ZJOI2007] 报表统计

    [ZJOI2007] 报表统计

    题目

    小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

    输入文件form.in第一行包含两个整数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

    OUTPUT

    2
    2
    1

    数据规模

    对于30%的数据,N≤ 1000 , M ≤ 5000
    对于100%的数据,N , M ≤500000
    对于所有的数据,序列内的整数不超过5×10^8。

    解题报告

    考试题的加强版,数据大了十倍
    考试打了个暴力,骗了20分= =
    正解:
    STL三件套——vec,que,还有set
    vector用来存每个位置后面加的元素
    priority_queue用来存相邻的差值,要用两个,一个存答案,一个用来垃圾回收(为什么要垃圾回收?当我们插入一个数时,我们将两个原本相连的数分开了,那么他们不再相连,所以我们要清理掉它)
    set用来处理全局最小差,我们可以用set找到一个数的前驱与后驱,而且显然的是,最小差一定存在于排完序后的相邻的数,所以我们可以进行预处理,边插入边更新
      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<vector>
      5 #include<queue>
      6 #include<set>
      7 using namespace std;
      8 inline int read(){
      9     int sum(0),f(1);
     10     char ch(getchar());
     11     for(;ch<'0'||ch>'9';ch=getchar())
     12         if(ch=='-')
     13             f=-1;
     14     for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar());
     15     return sum*f;
     16 }
     17 priority_queue<int,vector<int>,greater<int> >dust;
     18 priority_queue<int,vector<int>,greater<int> >ans1;
     19 vector<int>v[500002];
     20 multiset<int>st;
     21 multiset<int>::iterator it;
     22 int n,m;
     23 int w[500002];
     24 int ans2(0x7fffffff);
     25 char op[20];
     26 inline int my_max(int a,int b){
     27     return a>b?a:b;
     28 }
     29 inline int my_min(int a,int b){
     30     return a<b?a:b;
     31 }
     32 inline int jdz(int x){
     33     return x>=0?x:-x;
     34 }
     35 inline void insert(int x,int y){
     36     int size(v[x].size());
     37     if(x<n)
     38         dust.push(jdz(v[x][size-1]-v[x+1][0]));
     39     ans1.push(jdz(y-v[x][size-1]));
     40     if(x<n)
     41         ans1.push(jdz(y-v[x+1][0]));
     42     v[x].push_back(y);
     43     st.insert(y);
     44     it=st.find(y);
     45     if(it!=st.begin()){
     46         it--;
     47         int tmp(*it);
     48         ans2=my_min(jdz(y-tmp),ans2);
     49         it++;
     50     }
     51     if(it!=st.end()){
     52         it++;
     53         int tmp(*it);
     54         ans2=my_min(jdz(y-tmp),ans2);
     55     }
     56 }
     57 inline int query(){
     58     while(1){
     59         if(dust.empty()||dust.top()!=ans1.top())
     60             break;
     61         dust.pop();
     62         ans1.pop();
     63     }
     64     return ans1.top();
     65 }
     66 int main(){
     67   freopen("form.in","r",stdin);
     68   freopen("form.out","w",stdout);
     69     n=read(),m=read();
     70     for(int i=1;i<=n;i++){
     71         w[i]=read();
     72         st.insert(w[i]);
     73         it=st.find(w[i]);
     74         if(it!=st.begin()){
     75             it--;
     76             int tmp(*it);
     77             ans2=my_min(ans2,jdz(tmp-w[i]));
     78             it++;
     79         }
     80         if(it!=st.end()){
     81             it++;
     82             int tmp(*it);//cout<<tmp<<endl;
     83             ans2=my_min(ans2,jdz(tmp-w[i]));
     84         }
     85         if(i^1)
     86             ans1.push(jdz(w[i]-w[i-1]));
     87         v[i].push_back(w[i]);
     88 //      cout<<i<<' '<<w[i]<<' '<<ans2<<endl;
     89     }
     90     while(m--){
     91         scanf("%s",op);
     92         if(op[0]=='I'){
     93             int x(read()),y(read());
     94             insert(x,y);
     95         }
     96         else{
     97             if(strlen(op)<9)
     98                 printf("%d
    ",query());
     99             else
    100                 printf("%d
    ",ans2);
    101         }
    102     }
    103 }
    View Code
    好强大的STL啊= =
  • 相关阅读:
    算法竞赛入门经典训练指南
    git保护--git分支创建
    解决多个iframe嵌套而造成的多个滚动条问题
    css如何让div元素铺满整个屏幕
    第一个用python3写的爬虫小例子
    用JS获取当前页面的URL以及截取其中的字段
    css处理超出文本截断问题的两种情况(多行或者单行)
    约数的个数
    成绩排序
    八进制
  • 原文地址:https://www.cnblogs.com/hzoi-mafia/p/7277717.html
Copyright © 2011-2022 走看看