勤快的love枫[ZJOI2007]

勤快的love枫[ZJOI2007]

大家好,又见面了,我是全栈君。

题目描述

小绝恋love 枫是一个出纳,经常需要做一些统计报表的工作。今天是绝恋love 枫的生日,小绝恋love 枫希望可以帮爸爸分担一些工作,作为他的生日礼物之一。经过仔细观察,小绝恋love 枫发现统计一张报表实际上是维护一个非负整数数列,并且进行一些查询操作。在最开始的时候,有一个长度为的整数序列,并且有以下三种操作:INSERT i k 在原数列的第个元素后面添加一个新元素k;如果原数列的第个元素已经添加了若干元素,则添加在这些元素的最后(见下面的例子)

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。于是小绝恋love 枫写了一个程序,使得程序可以自动完成这些操作,但是他发现对于一些大的报表他的程序运行得很慢,你能帮助他改进程序么?

 

输入

第一行包含两个整数N,M,分别表示原数列的长度以及操作的次数。

第二行为个整数,为初始序列。

接下来的行每行一个操作,即“INSERT i k”,“MIN_GAP”,“MIN_SORT_GAP”中的一种(无多余空格或者空行)。

 

输出

对于每一个“MIN_GAP”和“MIN_SORT_GAP”命令,输出一行答案即可。

 

样例输入

3 5
5 3 1
INSERT 2 9
MIN_SORT_GAP
INSERT 2 6
MIN_GAP
MIN_SORT_GAP

样例输出

2
2
1

提示

对于30% 的数据,N≤1000,M≤5000

对于100% 的数据,N,M≤50000

对于所有的数据,序列内的整数不超过5*10^8。

 

题解

       一道显而易见的数据结构题,在数据结构题里几乎算不用动脑子的那种。前后最小的一下子想到钢哥讲过的垃圾堆,维护两个堆就可以实现有效答案的添加和删除。原数列也可以用一个副本数组,只维护目前最靠前和最靠后的值(考试时忘了下一个位置的开头元素还需要记录,炸了不少分)。但是整个序列中最相近的两个元素,就有些犯难。明明知道就应该建个平衡树找前驱后继,尴尬的情况是平衡树只打过Treap,Treap只打过两道题,还是一两周之前的事了,考场上打挂可能性极大。权衡了一下,还是拿了个数组暴力排序,唯一的优化是如果最小值已经为0就不再改动。算上这道题平衡树也只打过三道,简直不能算做过题。书到用时方恨少,事非经过不知难,从第一次见到这句话到现在已经有些年了,理解倒是越来越深了= =。

 

勤快的love枫[ZJOI2007]
勤快的love枫[ZJOI2007]

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cstdlib>
#include<cmath>
using namespace std;
const int sj=50010;
int n,m,a[sj],a1,a2,mi,g,q,h,jq,hj,size,d[sj];
priority_queue<int,vector<int>,greater<int> > qi;
priority_queue<int,vector<int>,greater<int> > du;
char c[20];
struct tree
{
     int l,r,v,rnd;
}t[sj];
int bj(int x,int y)
{
     return x<y?x:y;
}
void lturn(int &x)
{
     int tt=t[x].r;
     t[x].r=t[tt].l;
     t[tt].l=x;
     x=tt;
}
void rturn(int &x)
{
     int tt=t[x].l;
     t[x].l=t[tt].r;
     t[tt].r=x;
     x=tt;
}
void query_pre(int k,int x)
{
     if(k==0) return;
     if(t[k].v<x)
     {
         q=k;
         query_pre(t[k].r,x);
     }
     else query_pre(t[k].l,x);
}
void query_beh(int k,int x)
{
     if(k==0) return;
     if(t[k].v>x)
     {
        h=k;
        query_beh(t[k].l,x);
     }
     else query_beh(t[k].r,x);
}
void cr(int &x,int y)
{
     if(x==0)
     {
        size++;
        x=size;
        t[x].rnd=rand();
        t[x].v=y;
        return;
     }
     if(t[x].v==y)
     {
        jq=hj=y;
        q=h=1;
        return;
     }
     if(y>t[x].v)
     {
        cr(t[x].r,y);
        if(t[x].rnd>t[t[x].r].rnd) lturn(x);
     }
     if(y<t[x].v)
     {
        cr(t[x].l,y);
        if(t[x].rnd>t[t[x].l].rnd) rturn(x);
     }
}
void init()
{
    scanf("%d%d",&n,&m);
    mi=0x7fffffff;
    for(int i=1;i<=n;i++) 
    {
      scanf("%d",&a[i]);
      if(i!=1) qi.push(abs(a[i]-a[i-1]));
      if(mi) 
      {
        q=h=-1;
        jq=hj=0;
        cr(g,a[i]);
        if(q==-1)
        {
           query_beh(g,a[i]);
           query_pre(g,a[i]);
           if(q!=-1||h!=-1)
           {
             jq=(q==-1)?0x7fffffff:t[q].v;
             hj=(h==-1)?0x7fffffff:t[h].v;
             mi=bj(mi,abs(a[i]-jq));
             mi=bj(mi,abs(a[i]-hj));
           }
        }
        else mi=0;
      }
      memcpy(d,a,sizeof(a));
    }
}
void cl()
{
     for(int i=1;i<=m;i++)
     {
        scanf("%s",c);
        if(c[4]=='R')
        {
           scanf("%d%d",&a1,&a2);
           if(a1!=n)
           {
             qi.push(abs(a2-a[a1+1]));
             du.push(abs(a[a1+1]-d[a1]));
           }
           qi.push(abs(a2-d[a1]));
           d[a1]=a2;
           if(mi) 
           {
              q=h=-1;
              jq=hj=0;
              cr(g,a2);
              if(q==-1)
              {
                query_beh(g,a2);
                query_pre(g,a2);
                if(q!=-1||h!=-1)
                {
                  jq=(q==-1)?0x7fffffff:t[q].v;
                  hj=(h==-1)?0x7fffffff:t[h].v;
                  mi=bj(mi,abs(a2-jq));
                  mi=bj(mi,abs(a2-hj));
                }
              }
              else mi=0;
           }
        }
        if(c[4]=='G')
        {
           while(!qi.empty()&&!du.empty()&&qi.top()==du.top())
           {
              qi.pop();
              du.pop();
           }
           printf("%d\n",qi.top());
        }
        if(c[4]=='S') printf("%d\n",mi);
     }
}
int main()
{
    init();
    cl();
    return 0;
}

love

 

     在cogs上看到了这题,交了一下RE,发现数据范围是十倍……调了数组大小再交一遍,居然TLE了!据说堆可能会炸掉,不得已又改成了线段树。跑得确实快了,可是比堆难写得多啊。差点上两百行【抵制恶意缩行不良风气,从我做起!

勤快的love枫[ZJOI2007]
勤快的love枫[ZJOI2007]

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
const int sj=500010;
int n,m,a[sj],a1,a2,mi,g,q,h,jq,hj,size,d[sj],last;
struct xs
{
     int v,l,r;
}xds[sj*8];
char c[20];
struct tree
{
     int l,r,v,rnd;
}t[sj];
int bj(int x,int y)
{
     return x<y?x:y;
}
void lturn(int &x)
{
     int tt=t[x].r;
     t[x].r=t[tt].l;
     t[tt].l=x;
     x=tt;
}
void rturn(int &x)
{
     int tt=t[x].l;
     t[x].l=t[tt].r;
     t[tt].r=x;
     x=tt;
}
void query_pre(int k,int x)
{
     if(k==0) return;
     if(t[k].v<x)
     {
         q=k;
         query_pre(t[k].r,x);
     }
     else query_pre(t[k].l,x);
}
void query_beh(int k,int x)
{
     if(k==0) return;
     if(t[k].v>x)
     {
        h=k;
        query_beh(t[k].l,x);
     }
     else query_beh(t[k].r,x);
}
void cr(int &x,int y)
{
     if(x==0)
     {
        size++;
        x=size;
        t[x].rnd=rand();
        t[x].v=y;
        return;
     }
     if(t[x].v==y)
     {
        jq=hj=y;
        q=h=1;
        return;
     }
     if(y>t[x].v)
     {
        cr(t[x].r,y);
        if(t[x].rnd>t[t[x].r].rnd) lturn(x);
     }
     if(y<t[x].v)
     {
        cr(t[x].l,y);
        if(t[x].rnd>t[t[x].l].rnd) rturn(x);
     }
}
void build(int x,int z,int y)
{
     xds[x].l=z;
     xds[x].r=y;
     xds[x].v=0x7fffffff;
     if(z==y)  return;
     int mid=(z+y)>>1;
     build(x<<1,z,mid);
     build((x<<1)|1,mid+1,y);
}
void update(int x,int z,int y)
{
     if(xds[x].l==xds[x].r&&xds[x].l==z)
     {
        xds[x].v=y;
        return;
     }
     int mid=(xds[x].l+xds[x].r)>>1;
     if(z<=mid) 
     {
        update(x<<1,z,y);
        xds[x].v=bj(xds[(x<<1)|1].v,xds[x<<1].v);
     }
     else
     {
        update((x<<1)|1,z,y);
        xds[x].v=bj(xds[(x<<1)|1].v,xds[x<<1].v);
     }
}
void init()
{
    scanf("%d%d",&n,&m);
    mi=0x7fffffff;
    build(1,1,sj*2-5);
    for(int i=1;i<=n;i++) 
    {
      scanf("%d",&a[i]);
      if(i!=1) update(1,i-1,abs(a[i]-a[i-1]));
      if(mi) 
      {
        q=h=-1;
        jq=hj=0;
        cr(g,a[i]);
        if(q==-1)
        {
           query_beh(g,a[i]);
           query_pre(g,a[i]);
           if(q!=-1||h!=-1)
           {
             jq=(q==-1)?0x7fffffff:t[q].v;
             hj=(h==-1)?0x7fffffff:t[h].v;
             mi=bj(mi,abs(a[i]-jq));
             mi=bj(mi,abs(a[i]-hj));
           }
        }
        else mi=0;
      }
    }
    memcpy(d,a,sizeof(a));
    last=n-1;
}
void cl()
{
     for(int i=1;i<=m;i++)
     {
        scanf("%s",c);
        if(c[4]=='R')
        {
           scanf("%d%d",&a1,&a2);
           last++;
           update(1,last,abs(a2-d[a1]));
           update(1,a1,abs(a2-a[a1+1]));
           d[a1]=a2;
           if(mi) 
           {
              q=h=-1;
              jq=hj=0;
              cr(g,a2);
              if(q==-1)
              {
                query_beh(g,a2);
                query_pre(g,a2);
                if(q!=-1||h!=-1)
                {
                  jq=(q==-1)?0x7fffffff:t[q].v;
                  hj=(h==-1)?0x7fffffff:t[h].v;
                  mi=bj(mi,abs(a2-jq));
                  mi=bj(mi,abs(a2-hj));
                }
              }
              else mi=0;
           }
        }
        if(c[4]=='G') printf("%d\n",xds[1].v);
        if(c[4]=='S') printf("%d\n",mi);
     }
}
int main()
{
    init();
    cl();
    return 0;
}

form

 

 

转载于:https://www.cnblogs.com/moyiii-/p/7270753.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/108279.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 快速制作机房3D效果图教程「建议收藏」

    快速制作机房3D效果图教程「建议收藏」作者:广州麦景科技有限公司林鲁刚 原文接随着信息网络技术的不断发展,大量数据中心的建设,机房监控软件已经成为了机房管理者重要的管理工具,机房监控软件也从无到有,从2D到3D,从静态到三维动态的改进。不多说,直接上图↓以前是这样的现在是这样的或者这样的(麦景数据中心可视化管理平台)现在教大家如何画好一张机房效果图,所用软件有↓前期准备资料

    2022年6月2日
    56
  • LSTM模型搭建_LSTM神经网络

    LSTM模型搭建_LSTM神经网络defLSTM_Classifier(self,train,trainLabel,test,testLabel,val_test,val_label,new_test=None):train,test=np.array(train),np.array(test)train,test=train.reshape(train.shape[0],1,train.shape[1]),test.reshape(test.shape[0],1,tes…

    2022年9月11日
    0
  • hashmap为什么线程不安全面试_hashtable是线程安全的吗

    hashmap为什么线程不安全面试_hashtable是线程安全的吗HashMap为什么线程不安全?文章目录HashMap为什么线程不安全?前言项目环境1.put方法中的++modCount问题2.扩容期间取值不准确3.同时put碰撞导致数据丢失4.可见性问题5.扩容头插法可能导致的循环链表问题6.总结7.参考前言本文从以下几个方面来讨论HashMap为什么是线程不安全的put方法中的modCount++问题扩容期间取值不准确同时put碰撞导致数据丢失可见性问题扩容头插法可能导致的循环链表问题(jdk1.8以前版本)jd

    2022年10月11日
    0
  • ArcGis二次开发遇到的问题

    ArcGis二次开发遇到的问题在我们刚开始利用.net对arcgis进行二次开发时,费了牛鼻子劲安装好了arcgisengine,也在vs中建立了新项目,拖进去了工具条控件,主页面控件,想要欣赏一下成果的时候,发现一点击启动就报错了:查阅相关资料后发现,在主程序中加入这样两行代码,给程序进行授权,就可以顺利运行了。在这里强烈推荐牟乃夏老师的一系列书籍,从arcgis基础知识到开发自己的gis软件,非常有用。后面有时间我会…

    2022年7月23日
    5
  • oracle数据库菜鸟入门

    oracle数据库菜鸟入门所有应用软件之中,数据库可能是最复杂的。MySQL的手册有3000多页,PostgreSQL的手册有2000多页,Oracle的手册更是比它们相加还要厚。但是,自己写一个最简单的数据库,做起来并不难。Reddit上面有一个帖子,只用了几百个字,就把原理讲清楚了。下面是我根据这个帖子整理的内容。一、数据以文本形式保存第一步,就是将所要保存的数据,写入文本文件。这个文本文件就是你的数据库。为了方便读取,数据必须分成记录,每一条记录的长度规定为等长。比如,假定每条记录的长度是800字节,那

    2022年8月30日
    1
  • 冒泡排序(java代码实现)

    冒泡排序(java代码实现)冒泡排序和快速排序1、冒泡排序1.1介绍1.2代码实现1.2.1基本实现1.2.2优化2、快速排序2.1介绍2.2代码实现1、冒泡排序1.1介绍1.2代码实现1.2.1基本实现1.2.2优化2、快速排序2.1介绍2.2代码实现…

    2022年6月22日
    21

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号