P1966 火柴排队
知识点: 离散化,逆序对
题面
分析
首先对计算式进行转化:
可以发现, 不会被排列顺序所影响.
所以 只需要使 尽量大即可.
有 一结论:
使 为 数组中第 大 , 使 为 数组中第 大时,
对应位置相乘后的和最大
- 证明:
进行反证, 假设有:
设存在
则有:
因为 , 则有:
产生矛盾 , 得以反证. 原结论正确
则需要使 两数组中 对应大小的数字 相对应.
可以选择 固定数组 , 只改变数组 的顺序.
实现:
先对两数组进行离散化,
由于要将 数组作为标准 , 来改变 数组的顺序
所以对离散化后数组 建立映射 , 把b数组当前排列顺序 , 当做一个升序排列的数列
即: 使 ;
由于都已进行了离散化,
再将 数组中的数进行更改,
按照映射关系 , 为它们赋新值.
即: 使
然后需要将重赋值的 数组进行处理.
由于交换方式为 相邻两元素交换
即冒泡排序,
所以将其变为有序数列的代价 , 即数列中逆序对数.
使用归并排序 / 树状数组求逆序对即可
代码
复制复制#include<cstdio> #include<ctype.h> #include<algorithm> #include<map> #define mid (l+r)/2 #define int long long const int MARX = 1e6+10; const int mod = 99999997; //============================================================= int n,ans , a[MARX],b[MARX],a1[MARX],b1[MARX],tmp[MARX]; std::map <int,int> s1,s2,le;//离散化 + 映射关系 //============================================================= inline int read() { int fl=1,w=0;char ch=getchar(); while(!isdigit(ch) && ch!='-') ch=getchar(); if(ch=='-') fl=-1; while(isdigit(ch)){w=w*10+ch-'0',ch=getchar();} return fl*w; } void prepare() { n=read(); for(int i=1;i<=n;i++) a[i]=a1[i]=read(); for(int i=1;i<=n;i++) b[i]=b1[i]=read(); std::sort(a1+1,a1+n+1);//离散化a数组 for(int i=1;i<=n;i++) if(a1[i]!=a1[i-1]) s1[a1[i]]=s1[a1[i-1]]+1; std::sort(b1+1,b1+n+1);//离散化b数组 for(int i=1;i<=n;i++) if(b1[i]!=b1[i-1]) s2[b1[i]]=s2[b1[i-1]]+1; for(int i=1;i<=n;i++)//对离散化后的b数组建立映射关系 if(b[i]!=b[i-1]) le[s2[b[i]]]=le[s2[b[i-1]]]+1; for(int i=1;i<=n;i++) a[i]=le[s1[a[i]]];//按照离散化后的映射关系,重新为a数组赋值 } void merge(int l,int r)//归并排序,合并 { int i=l,j=mid+1,k=1; for(;i<=mid && j<=r;) if(a[i]<=a[j]) tmp[k++]=a[i++]; else tmp[k++]=a[j++],ans=(ans+(mid-i+1))%mod;//产生逆序对 while(i<=mid) tmp[k++]=a[i++]; while(j<=r) tmp[k++]=a[j++]; for(i=l;i<=r;i++) a[i]=tmp[i-l+1];//重新赋值给a数组 } void spile(int l,int r)//归并排序,拆分 { if(l>=r) return ; spile(l,mid); spile(mid+1,r);//二分 merge(l,r); } //============================================================= signed main() { prepare(); spile(1,n); printf("%lld",ans); }
作者@Luckyblock,转载请声明出处。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】