【JZOJ5947】【NOIP2018模拟11.02】初音未来(miku)(逆序对排序+线段树)

2023-10-22 09:30

本文主要是介绍【JZOJ5947】【NOIP2018模拟11.02】初音未来(miku)(逆序对排序+线段树),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Description

  • Hercier作为一位喜爱Hatsune Miku的OIer,痛下决心,将Vocaloid买回了家。打开之后,你发现界面是一个长为n的序列,代表音调,并形成了全排列。你看不懂日语,经过多次尝试,你只会用一个按钮:将一段区间按升序排序。不理解音乐的Hercier决定写一个脚本,进行m次操作,每次对一段区间进行操作。可惜Hercier不会写脚本,他找到了在机房里的你,请你模拟出最后的结果。

Input

在这里插入图片描述

Output

在这里插入图片描述

Data Constraint

在这里插入图片描述

Solution

  • 我们知道冒泡排序的交换次数是逆序对个数;而冒泡排序的交换方法是交换相邻逆序对。
  • 既然这样,可以将本题的排序变为逆序对排序。我们记录下所有的相邻逆序对,用一棵线段树存储一段区间中最左边的相邻逆序对。对于询问 ( l i , r i ) (l_i,r_i) (li,ri),我们不断地寻找区间 [ l i , r i ] [l_i,r_i] [li,ri]中最靠左的相邻逆序对,若找得到,则交换之,同时维护线段树。
  • 分析一波时间复杂度。我们至多进行 n 2 n^2 n2次交换,每次交换前需要 log ⁡ 2 n \log_2n log2n的查询时间,交换后需要 log ⁡ 2 n \log_2n log2n的维护时间。因此,总时间复杂度为 O ( ( n 2 + m ) log ⁡ 2 n ) O((n^2+m)\log_2n) O((n2+m)log2n)

Code

#include <bits/stdc++.h>
#define A v<<1
#define B A|1
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;const int N=1501;
int i,n,m,L,R,a[N],px,pv,t[N*N],x,y,pos;inline int min(int x,int y) {return x<y?x:y;}void read(int&x)
{char ch=getchar(); x=0;for(;!isdigit(ch);ch=getchar());for(;isdigit(ch);ch=getchar()) x=(x<<3)+(x<<1)+(ch^48);
}void modify(int v,int l,int r)
{if(l==r) {t[v]=pv; return;}int mid=l+r>>1;px<=mid ? modify(A,l,mid) : modify(B,mid+1,r);t[v]=min(t[A],t[B]);
}
void ins(int i)
{px=i; pv=(a[i]>a[i+1]?i:n+1);modify(1,1,n);
}int query(int v,int l,int r)
{if(x<=l&&r<=y) return t[v];if(y< l||r< x) return n+1;int mid=l+r>>1;return min(query(A,l,mid),query(B,mid+1,r));
}int main()
{freopen("miku.in","r",stdin);freopen("miku.out","w",stdout);read(n); read(m); read(L); read(R);memset(t,127,sizeof t);fo(i,1,n) {read(a[i]);if(i>1) ins(i-1);}fo(i,1,m){read(x); read(y);rep:pos=query(1,1,n);if(pos>=y) continue;swap(a[pos],a[pos+1]);if(pos>1) ins(pos-1);ins(pos); ins(pos+1);goto rep;}fo(i,L,R) printf("%d ",a[i]);
}

这篇关于【JZOJ5947】【NOIP2018模拟11.02】初音未来(miku)(逆序对排序+线段树)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/260565

相关文章

大数据小内存排序问题如何巧妙解决

《大数据小内存排序问题如何巧妙解决》文章介绍了大数据小内存排序的三种方法:数据库排序、分治法和位图法,数据库排序简单但速度慢,对设备要求高;分治法高效但实现复杂;位图法可读性差,但存储空间受限... 目录三种方法:方法概要数据库排序(http://www.chinasem.cn对数据库设备要求较高)分治法(常

Python中lambda排序的六种方法

《Python中lambda排序的六种方法》本文主要介绍了Python中使用lambda函数进行排序的六种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录1.对单个变量进行排序2. 对多个变量进行排序3. 降序排列4. 单独降序1.对单个变量进行排序

关于Java内存访问重排序的研究

《关于Java内存访问重排序的研究》文章主要介绍了重排序现象及其在多线程编程中的影响,包括内存可见性问题和Java内存模型中对重排序的规则... 目录什么是重排序重排序图解重排序实验as-if-serial语义内存访问重排序与内存可见性内存访问重排序与Java内存模型重排序示意表内存屏障内存屏障示意表Int

poj3468(线段树成段更新模板题)

题意:包括两个操作:1、将[a.b]上的数字加上v;2、查询区间[a,b]上的和 下面的介绍是下解题思路: 首先介绍  lazy-tag思想:用一个变量记录每一个线段树节点的变化值,当这部分线段的一致性被破坏我们就将这个变化值传递给子区间,大大增加了线段树的效率。 比如现在需要对[a,b]区间值进行加c操作,那么就从根节点[1,n]开始调用update函数进行操作,如果刚好执行到一个子节点,

hdu1394(线段树点更新的应用)

题意:求一个序列经过一定的操作得到的序列的最小逆序数 这题会用到逆序数的一个性质,在0到n-1这些数字组成的乱序排列,将第一个数字A移到最后一位,得到的逆序数为res-a+(n-a-1) 知道上面的知识点后,可以用暴力来解 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#in

hdu1689(线段树成段更新)

两种操作:1、set区间[a,b]上数字为v;2、查询[ 1 , n ]上的sum 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>#include<map>#include<stdio.h>#include<stdl

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c