• [BZOJ4552]:[Tjoi2016&Heoi2016]排序(桶排序)


    题目传送门


    题目描述

    在2016年,佳媛姐姐喜欢上了数字序列。

    因而她经常研究关于序列的一些奇奇怪怪的问题,现在她在研究一个难题,需要你来帮助她。

    这个难题是这样子的:给出一个1到n的全排列,现在对这个全排列序列进行m次局部排序,排序分为两种:1:(0,l,r)表示将区间[l,r]的数字升序排序2:(1,l,r)表示将区间[l,r]的数字降序排序最后询问第q位置上的数字。


    输入格式

    输入数据的第一行为两个整数n和m。n表示序列的长度,m表示局部排序的次数。
    第二行为n个整数,表示1到n的一个全排列。
    接下来输入m行,每一行有三个整数op,l,r,op为0代表升序排序,op为1代表降序排序,l,r表示排序的区间。
    最后输入一个整数q,q表示排序完之后询问的位置。


    输出格式

    输出数据仅有一行,一个整数,表示按照顺序将全部的部分排序结束后第q位置上的数字。


    样例

    样例输入

    6 3
    1 6 2 5 3 4
    0 1 4
    1 3 6
    0 2 4
    3

    样例输出

    5


    数据范围与提示

    $1leqslant n,mleqslant {10}^5$

    $1leqslant qleqslant n$


    题解

    它放在了“不打正解的我”这一板块,正解是线段树,时间复杂度$Theta (mlog^2n)$。

    确实,这道题我打的暴力。

    首先考虑暴力sort,时间复杂度:$Theta (m imes nlog n)$。

    但是,$10^5$的数据范围显然跑不过,于是我便想到了一个并不常用的排序方法:桶排序。

    这道题保证了这$n$个数是$n$的全排列,于是桶排序可行。

    但是稳妥的桶排序在统计答案的时候需要扫整个区间,在$m$次询问后时间复杂度会变为$Theta (n imes m)$,显然有不可做了。

    那么我在往桶里放数的时候标记一下放进去的最大值和最小值,然后在往外拿的时候只扫描这个区间,成功卡过,甚至比某些打的不怎么优秀的线段树还要快。

    码长和内存才是亮点。


    代码时刻

    #include<bits/stdc++.h>
    using namespace std;
    int a[100001],t[100001];
    void change0(int l,int r)//升序
    {
    	int maxn=0,minn=20020923,flag=l;
    	for(int i=l;i<=r;i++)
    	{
    		t[a[i]]=1;
    		minn=min(minn,a[i]);
    		maxn=max(maxn,a[i]);
    	}
    	for(int i=minn;i<=maxn;i++)
    		if(t[i])a[flag++]=i,t[i]=0;
    }
    void change1(int l,int r)//降序
    {
    	int maxn=0,minn=20020923,flag=l;
    	for(int i=l;i<=r;i++)
    	{
    		t[a[i]]=1;
    		minn=min(minn,a[i]);
    		maxn=max(maxn,a[i]);
    	}
    	for(int i=maxn;i>=minn;i--)
    		if(t[i])a[flag++]=i,t[i]=0;
    }
    int main()
    {
    	int n,m;
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++)
    		scanf("%d",&a[i]);
    	while(m--)
    	{
    		int op,l,r;
    		scanf("%d%d%d",&op,&l,&r);
    		if(op)change1(l,r);
    		else change0(l,r);
    	}
    	scanf("%d",&n);
    	printf("%d",a[n]);
    	return 0;
    }
    

    rp++

  • 相关阅读:
    【Linux 读书笔记】Linux文件的硬连接和符号连接
    Shell参数
    Shellcase语句的例子
    Shellselect
    Shell小程序一个
    SHELL起步
    接昨天的 while
    Shell循环控制
    Shellwhile循环的例子
    Shellfor语句
  • 原文地址:https://www.cnblogs.com/wzc521/p/11237206.html
Copyright © 2020-2023  润新知