【BZOJ - 1058】 ZJOI2007 报表统计

    · 蒟蒻题解, 大神轻虐.

    · 各种丑代码.

    · 各种绕弯子.



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


    因为最近铺天盖地的考试导致BZOJ荒废了好一阵子......

    一上来就一道数据结构题…… (湖南什么时候少考点数学题多考点数据结构啊> <)

    预计Splay会被卡死所以就没写了.

    因为没有删除操作所以就各种乱搞什么的……

    Min_Gap : 考虑每次加入一个元素就相当于挂个链……并且这个链最多只有N个地方会被添加元素.  所以那些可能会被添加元素的开个堆维护, 其余直接取最小就行了,

    Max_Sort_Gap :  离散化 + 线段树……100w的数组Sort什么的0.5s应该就能出了......


    于是Rank 3 ... 好吧代码好长.


    突然看到某人


    代码也太短了吧= =!

    于是就Google娘题解去了.

    于是就被STL库怒D一记.

    好吧说起来在考场用STL岂不是轻轻松松三分钟打完程序么 (等等怎么感觉这句话有点问题......)     


    用Set就可以水过了……T T.

    放出我的丑代码……大神轻虐.

#include <cstdio>
#include <cstdlib>
#include <algorithm>
#define mid ((l + r) >> 1)
char c;
#define gs ((c < '0' || c > '9')  &&  c != '-')
int getint() { int wis = 0, q = 0; c = getchar(); while (gs) c = getchar(); if (c == '-')  q = 1, c = getchar(); while (!gs) wis = wis * 10 + c - '0', c = getchar(); return q ? -wis : wis; }
const int INF = ~0U>>1, ys = 500010;
using namespace std;

int n, m, k, dima, sg, sgp, last;
bool t[ys * 2];
int max_p[ys * 6], min_p[ys * 6], tot[ys * 6];
int hep[ys], pos[ys], wap[ys], sta[ys], now[ys];
int y[ys], x[ys], p[ys * 2], g[ys * 2], st[ys * 2], v[ys * 2]; 

void build(int l, int r, int k)
{
    if (l == r)  {  tot[k] = INF;  st[l] = k;
      if (t[l])  max_p[k] = min_p[k] = v[g[l]];  
      else  min_p[k] = INF >> 1, max_p[k] = -(INF >> 1);  return;
      }    
    build(l, mid, k << 1);  build(mid + 1, r, (k << 1) + 1);
    max_p[k] = max(max_p[k << 1], max_p[(k << 1) + 1]);
    min_p[k] = min(min_p[k << 1], min_p[(k << 1) + 1]); 
    tot[k] = min(abs(min_p[(k << 1) + 1] - max_p[k << 1]), min(tot[k << 1], tot[(k << 1) + 1]));
}
void update(int k, int v)
{
    min_p[k] = max_p[k] = v;
    for (; k >>= 1; )
      max_p[k] = max(max_p[k << 1], max_p[(k << 1) + 1]),
      min_p[k] = min(min_p[k << 1], min_p[(k << 1) + 1]), 
      tot[k] = min(abs(min_p[(k << 1) + 1] - max_p[k << 1]), min(tot[k << 1], tot[(k << 1) + 1]));  
}
void up(int w)
{
    int last = hep[w];
    for (; (w >> 1)  &&  wap[hep[w >> 1]] > wap[last]; w >>= 1)
      pos[hep[w >> 1]] = w,
      hep[w] = hep[w >> 1];
    pos[last] = w;  hep[w] = last;  
}
void down(int w)
{
    int j, last = hep[w];
    for (; j = w << 1, j <= sgp  &&  (wap[hep[j]] < wap[last]  ||  j < sgp  &&  
         wap[hep[j + 1]] < wap[last]); pos[hep[j]] = w, hep[w] = hep[j], w = j)
    if (j < sgp  &&  wap[hep[j]] > wap[hep[j + 1]]) ++j;
    pos[last] = w;
    hep[w] = last;
}
void change(int w)
{
    if (w >> 1  &&  wap[hep[w >> 1]] > wap[hep[w]])  up(w);
    else  down(w); 
}  
bool cmp(const int &a, const int &b)
{
    return v[a] < v[b];
}        
int main()
{
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    n = getint(); m = getint();  sg = n;
    for (int i = 1; i <= n; ++i)  
      sta[i] = now[i] = v[i] = getint(), g[i] = i;
    dima = INF;
    for (int i = 1; i < n; ++i)
      ++sgp, wap[i] = abs(sta[i + 1] - sta[i]), pos[i] = hep[i] = i, change(i);
    for (int i = 1; i <= m; ++i)
      {
          while (c != 'I'  &&  c != 'M')  c = getchar();
          if (c == 'I')  {  y[i] = 1;
            k = getint(); v[++sg] = getint(); g[sg] = sg;
            if (dima == 0)  continue; 
            dima = min(dima, abs(v[sg] - now[k])); wap[k] = abs(sta[k + 1] - v[sg]); now[k] = v[sg];
            if (k == n)  continue;  change(pos[k]);
          }
          else
          if (scanf("%c%c%c%c", &c, &c, &c, &c), c == 'S')  y[i] = 2;
          else  y[i] = 3, x[i] = min(dima, wap[hep[1]]);
      }     dima = INF;
    sort(g + 1, g + sg + 1, cmp);
    for (int i = 1; i <= sg; ++i)  p[g[i]] = i, t[i] = g[i] <= n ? true : false;
    build(1, sg, 1);  sg = n;
    for (int i = 1; i <= m; ++i)
      if (y[i] == 1)  
        if (tot[1] != 0)  ++sg, update(st[p[sg]], v[sg]);  else;  else
      if (y[i] == 2)  printf("%d\n", tot[1]);  else
        printf("%d\n", x[i]);              
}

   


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值