zoukankan      html  css  js  c++  java
  • 黑盒子

    题目

    题目

    解法

    这不是用平衡树随便搞吗

    怎么可能用这么复杂的代码!!!(╯‵□′)╯︵┻━┻

    实在不行用离散化加主席树也可以啊

    怎么可能打线段树啊(╯‵□′)╯︵┻━┻

    树状数组加二分也行啊,你不嫌弃直接树状数组也可以啊

    也不想打啊(╯‵□′)╯︵┻━┻

    平衡树不是有STL吗?

    不用STL(╯‵□′)╯︵┻━┻

    那就用整体二分啊

    不会(╯‵□′)╯︵┻━┻

    然后后面学了。

    这里,我们仔细思考一下,这个其实就是询问第(k)大,但是这个(k)竟然是递增的,这意味着我们可以使用堆,然后每次查询完一次第(k)大,然后把堆顶踢出去,这样(k+1)大就又是堆顶啦!!!!完美。

    然后我WA了。。。。

    仔细思考一下,堆顶的元素虽然在连续的询问中不可能再出现了,但是如果询问完第(k)大后插入个比它小的作替死鬼,这样下次问第(k+1)大就还是这个堆顶了啊。

    于是我们需要一个可以有后悔操作的工具堆,没错,就是对顶堆。

    我们把删除的数字全部放到一个大根堆中,如果这个时候插入的数字(x)比堆头小,那么就把(x)插入到大根堆中,把大根堆原来的堆顶插入回小根堆中参与询问。

    对顶堆NB!!!!

    当然我是手打堆,代码好长(╯‵□′)╯︵┻━┻。

    代码

    (O(nlogn))

    #include<cstdio>
    #include<cstring>
    #define  N  31000
    using  namespace  std;
    int  a[N],n,m,b[N];
    inline  void  wap(int  &x,int  &y){int  t=x;x=y;y=t;}
    struct  xiao_dui
    {
    	int  a[N],tot;
    	void  ins(int  x)
    	{
    		a[++tot]=x;int  now=tot;
    		while(now>1)
    		{
    			int  i=now>>1;
    			if(a[i]>a[now])wap(a[i],a[now]),now=i;
    			else  break;
    		}
    	}
    	int  pop()
    	{
    		int  ans=a[1];wap(a[1],a[tot]);tot--;
    		int  now=1;
    		while((now<<1)<=tot)
    		{
    			int  i=now<<1;
    			if(i<tot  &&  a[i+1]<a[i])i++;
    			if(a[i]<a[now])wap(a[i],a[now]),now=i;
    			else  break;
    		}
    		return  ans;
    	}
    }a1;
    struct  da_dui
    {
    	int  a[N],tot;
    	void  ins(int  x)
    	{
    		a[++tot]=x;int  now=tot;
    		while(now>1)
    		{
    			int  i=now>>1;
    			if(a[i]<a[now])wap(a[i],a[now]),now=i;
    			else  break;
    		}
    	}
    	int  pop()
    	{
    		int  ans=a[1];wap(a[1],a[tot]);tot--;
    		int  now=1;
    		while((now<<1)<=tot)
    		{
    			int  i=now<<1;
    			if(i<tot  &&  a[i+1]>a[i])i++;
    			if(a[i]>a[now])wap(a[i],a[now]),now=i;
    			else  break;
    		}
    		return  ans;
    	}
    	int  top(){return  tot==0?-999999999:a[1];}
    }a2;
    int  main()
    {
    	scanf("%d%d",&n,&m);
    	for(int  i=1;i<=n;i++)scanf("%d",&a[i]);
    	for(int  i=1;i<=m;i++)
    	{
    		scanf("%d",&b[i]);
    		b[i]=b[i]-i+1;
    	}
    	int  t=0;
    	for(int  i=1;i<=n;i++)
    	{
    		if(a[i]<a2.top())
    		{
    			a1.ins(a2.pop());
    			a2.ins(a[i]);
    		}
    		else  a1.ins(a[i]);
    		while(a1.tot==b[t+1]  &&  t<m)
    		{
    			t++;
    			int  x=a1.pop();a2.ins(x);
    			printf("%d
    ",x);
    		}
    		if(t==m)break;
    	}
    	return  0;
    }
    
  • 相关阅读:
    详解ASP.NET中获取小程序二维码图片的操作<后端>
    ASP.NET 后台上传图片
    使用Js在前台画二维码
    在网页上点击图片打开一个新页面显示大图
    C# 使用RabbitMQ消息队列
    Git如何拉取指定远程分支
    win10专业版激活方法
    基于.Net Core3.1 MVC + EF Core的项目(一)框架的初步搭建
    session未过期就丢失的原因以及处理方式
    DES加密和base64加密
  • 原文地址:https://www.cnblogs.com/zhangjianjunab/p/13386172.html
Copyright © 2011-2022 走看看