首页 > 其他分享 >海亮01/10构造专题

海亮01/10构造专题

时间:2024-01-10 14:22:06浏览次数:34  
标签:10 ch 海亮 交换 le 01 ans 排列

海亮01/10构造专题

个人题单

T1

CF1375E

题意

给定一个长度为 \(n\) 的序列 \(a\),求 \(a\) 中的所有逆序对 \((i_1, j_1), (i_2, j_2), \cdots, (i_m, j_m)\) 的一个排列 \(p\),

使得依次交换 \((a_{i_{p_1}}, a_{j_{p_1}}), (a_{i_{p_2}}, a_{j_{p_2}}), \cdots, (a_{i_{p_m}}, a_{j_{p_m}})\) 后序列单调不降。

\(1 \le n \le 10^3\),\(1 \le a_i \le 10^9\)。

题解

先将原数组从小到大编号(如果两个数大小相同,那么按照下标从小到大编号)变成排列 \(b\)。

我们可以想到,每次考虑将最左边的位置 \(i\) 进行交换使得满足以下两条:

  • 让位置 \(i\) 最终填上数字 \(i\)。
  • 不改变剩下数字的相对位置。

然后问题就缩减成了 \([i+1,n]\)

然后你再想想,就会发现这玩应好像冒泡排序。

具体而言,每次需要填位置 \(i\),那么就从小到大(\(1\to i-1\))的交换满足 \(a_j>a_i\) 的 \(j\)。

但是但是,冒泡排序要求交换的是相邻的两个元素,怎么样才能交换不相邻的两个数呢?

然后发现有个神奇的东西叫做逆排列(设排列 \(p\),那么他的逆排列 \(q\) 需要满足 \(q_{p_i}=i\))

发现,如果 \((i,j)\) 在排列 \(p\) 中是逆序对,那么有 \(i<j,p_i>p_j\),而显然 \(q_{p_i}<q_{p_j},p_i>p_j\),也就是说,\((p_i,p_j)\) 在排列 \(q\) 中是逆序对(充要条件)。从小到大交换仍然满足刚刚的策略。

然后对着 \(q\) 冒泡排序即可,构造的话直接记录下来 \(q\) 的交换历程即可。

代码

#include<bits/stdc++.h>
using namespace std;
inline int read(){
	int x = 0, f = 1;char ch = getchar();
	while(ch < '0' || ch > '9'){if(ch == '-') f = -1;ch = getchar();}
	while(ch >= '0' && ch <= '9'){x = (x << 1) + (x << 3) + (ch ^ 48);ch = getchar();}
	return x * f;
}
const int maxn = 1e3 + 10;
int b[maxn], n;
struct node{
	int num, id, nid;
	node(int num = 0,int id = 0,int nid = 0):num(num),id(id),nid(nid){}
}a[maxn];
struct cmp1{bool operator () (node a,node b){return a.num != b.num ? a.num < b.num : a.id < b.id;}};
struct cmp2{bool operator () (node a,node b){return a.id < b.id;}};
vector<pair<int,int> > ans;
signed main(){
	n = read();
	for(int i = 1;i <= n;i++){a[i] = node(read(),i);}
	sort(a + 1,a + 1 + n,cmp1());
	for(int i = 1;i <= n;i++)a[i].nid = i;
	sort(a + 1,a + 1 + n,cmp2());
	for(int i = 1;i <= n;i++)b[a[i].nid] = i;
//	for(int i = 1;i <= n;i++)printf("%d ",b[i]);puts("");
	for(int i = 1;i <= n;i++){
		for(int j = 1;j < n;j++){
			if(b[j] > b[j + 1]){
				swap(b[j],b[j + 1]);
				ans.push_back(make_pair(b[j],b[j + 1]));
			}
		}
	}
	
	printf("%d\n",ans.size());
	for(auto i : ans)printf("%d %d\n",i.first,i.second);
	return 0;
}

标签:10,ch,海亮,交换,le,01,ans,排列
From: https://www.cnblogs.com/Call-me-Eric/p/17956394

相关文章

  • 2024-01-10(电动车充电器&铁板烧)
    一、电动车充电器问题:(问题):充电器上电时炸了,新买了一个。坏的那家1年内免费换新还需等财务统一核销。(反思):充电器这种东西不能放在户外日晒雨淋,晚上把小电动清理干净。 二、鹿仙子铁板烧问题:(问题):500W/220V铁板上融锡膏好像要一分钟。这一分钟之前元器件都不会被烧坏吗?(解......
  • Oracle 10g enqueue waits
    Oracle10genqueuewaitsEnqueueTypeDescriptionenq:AD–allocateAUSynchronizesaccessestoaspecificOSM(OracleSoftwareManager)diskAUenq:AD–deallocateAUSynchronizesaccessestoaspecificOSMdiskAUenq:AF–tasks......
  • 关闭 Win10 自动更新
    方法一 Windows设置1. 按“Windows+I”键,打开Windows设置,再单击“更新和安全”。2. 然后,在Windows更新,单击“高级选项”。 3. 在高级选项中,您可以将“更新选项”中项目全部关闭,或者选择“暂停更新”,但此暂停更新至多只能暂停35天,   达到暂停限制后需先获取新......
  • 双向广搜->字符变换(洛谷P1032)
    题意:给起始和终止串A和B,以及不超过6个字符串变换规则,求A->B能否在10步以内变换完成。分析:暴力bfs每次有6条路可以走,时间复杂度是6^10大概6e8的时间复杂度,会TLE。于是这题是一道经典的双向bfs。直接开两个队列,两个map,暴力搜1~5步即可。双向bfs的时间复杂度是2*(6^5)=1e4......
  • D55XT100-ASEMI电机专用整流桥D55XT100
    编辑:llD55XT100-ASEMI电机专用整流桥D55XT100型号:D55XT100品牌:ASEMI封装:DXT-4平均正向整流电流(Id):55A最大反向击穿电压(VRM):1000V产品引线数量:4产品内部芯片个数:4产品内部芯片尺寸:95MIL峰值正向漏电流:<10ua恢复时间:>2000ns正向浪涌电流:550A芯片材质:光阻GPP最大正向电压:工作结温:-55℃~15......
  • 韩顺平java基础-10-面向对象编程
    韩顺平java基础-10-面向对象编程类变量和类方法类变量static静态变量被同一个类所有对象共享类变量在类加载的时候生成定义语法访问修饰符static数据类型变量名如何访问类变量类名.类变量名//类变量随着类加载而创建,所以即使没有创建对象实例也可以访问。使用细......
  • 将开发板设计拆解为10个部分,教你DIY属于年轻人的第一块Linux开发板
    本项目是基于全志F1C200S设计的开源屏幕开发板,设计的目标是提供一个低成本、超迷你且适合Linux开发的平台,特别是针对屏幕接口的支持。项目简介开发板板载16Mnorflash,主控芯片采用F1C200S,内置64MDRAM。同时附带USBHost接口以及USBtype-c口,以及CH340串口转USB芯片,用于开发调试使......
  • 【2024-01-09】期待自己
    20:00假如运气是雨滴,希望你是密西西比河。                                                 ——海明威昨天被老板约谈说,问我规划的最新产品什么时候可以出第一个版本......
  • rime中州韵 输入效果一览 100+增强功能效果
    rime是一个定制化程度很高的输入法框架,我们可以在该框架上搭建适合自己的输入法程序。我们将在专栏小狼毫Rime保姆教程中完成以下近百种定制化效果的配置与演示。欢迎订阅。以下为个性化定制的输入效果:......
  • 【愚公系列】2024年01月 WPF控件专题 ComboBox控件详解
    ......