zoukankan      html  css  js  c++  java
  • bzoj 1058 [ZJOI2007]报表统计(set)

    【题目链接】

        http://www.lydsy.com/JudgeOnline/problem.php?id=1058

    【题意】

        一个序列,提供插入,查询相邻最小差值,查询任意最小差值的操作。

    【思路】

        Set

        用两个set,listed装所有的相邻差值,sorted装所有的数。然后用front[x],last[x]记录位置x上开始和结束的数。

        对于Insert,维护listed:删除front[x+1]与last[x]的差值并插入两个新的差值,插入sorted后与前一个后一个作差更新答案。

    【代码】

     1 #include<cmath>
     2 #include<set>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<iostream>
     6 #define ite multiset<int>::iterator
     7 using namespace std;
     8 
     9 typedef long long ll;
    10 const int N = 3e6+10;
    11 
    12 multiset<int> sorted,listed;
    13 
    14 int n,m,tomin;
    15 int last[N],front[N];
    16 
    17 ll read() {
    18     char c=getchar();
    19     ll f=1,x=0;
    20     while(!isdigit(c)) {
    21         if(c=='-') f=-1; c=getchar();
    22     }
    23     while(isdigit(c))
    24         x=x*10+c-'0',c=getchar();
    25     return x*f;
    26 }
    27 int abs(int x) { return x<0? -x:x; }
    28 
    29 int main()
    30 {
    31     n=read(); m=read();
    32     tomin=1e9;
    33     for(int i=1;i<=n;i++) {
    34         front[i]=read();
    35         last[i]=front[i];
    36         sorted.insert(front[i]);
    37         if(i!=1) listed.insert(abs(front[i]-front[i-1]));
    38     }
    39     ite l;
    40     for(ite r=sorted.begin();r!=sorted.end();r++) {
    41         if(r!=sorted.begin()) 
    42             tomin=min(tomin,abs(*r-*l));
    43         l=r;
    44     }
    45     char op[20]; int x,y;
    46     while(m--) {
    47         scanf("%s",op);
    48         if(op[0]=='I') {
    49             x=read(),y=read();
    50             ite it=sorted.insert(y);
    51             if(it!=sorted.begin())
    52                 --it , tomin=min(tomin,abs(y-*it)) , ++it;
    53             if(it!=sorted.end())
    54                 ++it , tomin=min(tomin,abs(*it-y)) , --it;
    55             it=listed.find(abs(front[x+1]-last[x]));
    56             listed.erase(it);
    57             listed.insert(abs(y-front[x+1]));
    58             listed.insert(abs(y-last[x]));
    59             last[x]=y;
    60         } else
    61         if(strlen(op)==7) {
    62             printf("%d
    ",*listed.begin());
    63         } else {
    64             printf("%d
    ",tomin);
    65         }
    66     }
    67     return 0;
    68 }
  • 相关阅读:
    C语言利用fgetc复制拷贝文件内容
    linux 安装gcc 和 g++
    C宏定义和使用
    C的realloc的动态分配扩展和缩小内存
    C用malloc 向系统申请一个大小为n*4个字节的内存块
    GDB core命令的使用调试段错误
    GDB的安装
    C字符指针数组的使用
    C二维字符数组的使用及如何获取二维数组的总行数和总列数!
    C二维数组用指针地址遍历
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5276010.html
Copyright © 2011-2022 走看看