P5749 [IOI2019] 排列鞋子
算是一种新思路吧。
题目要求我们求最少的对调次数,想到了什么?求逆序对个数,我们只需将原来的 \(S_i\) 数组转化一下,求其逆序对个数即可。
转化规则为:从头开始,对于每个还未被赋值的 \(S_i\) 找在它后面离它最近的并于其符号相反的 \(S_i\)。将 \(sum+2\)(其初值为 \(0\)),其中的正数赋值为 \(sum\),负数赋值为 \(sum-1\)。
例如样例一,赋值完毕的数组为:2 4 3 1。
样例二为 1 2 4 3 5 6。
正确性的证明:因为每次找的都是最近的 \(S_i\),所以总交换次数最少。而数组的重新排列保证了左右两只鞋子分配到的数字一定是 \(sum-1\) 与 \(sum\)。此时问题就变成了求将一个无序的序列转化为有序,最少需要几次交换,求逆序对个数即可。
#include <bits/stdc++.h>
using namespace std;
const int N=2e5+7;
map<int,list<int> > m;
int a[N],tr[N],s[N];
bitset<N> vis;
int n;
void upd(int w,int x){
for(int i=w;i<=n;i+=(i&-i)) tr[i]+=x;
}
int query(int x){
int ans=0;
while(x>0){
ans+=tr[x];
x-=(x&-x);
}
return ans;
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n;
n*=2;
for(int i=1;i<=n;i++){
cin>>s[i];
m[s[i]].push_back(i);
}
for(int i=1,sum=0;i<=n;i++){
if(vis[i]) continue;
int j=m[-s[i]].front();//找在它后面离它最近的并于其符号相反的 Si.
m[s[i]].pop_front();
m[s[j]].pop_front();
vis[i]=vis[j]=1;
sum+=2;
if(s[i]<0) a[i]=sum-1,a[j]=sum;
else a[j]=sum-1,a[i]=sum;
}
//树状数组求逆序对。
long long ans=0;
for(int i=1;i<=n;i++) {
upd(a[i],1);
ans+=i-query(a[i]);
cout<<a[i]<<' ';
}
cout<<ans;
return 0;
}
P5749 [IOI2019] 排列鞋子的更多相关文章
- LOJ 3175. 「IOI2019」排列鞋子
传送门 考虑如果能确定每个鞋子最终交换到的位置,那么答案容易算出 具体地,如果原位置为 $i$ 的鞋子要交换到 $pos[i]$ 那么最终答案就是 $pos$ 的逆序对数量 如果不懂可以先去写 NOI ...
- [loj3175]排列鞋子
贪心与最近的鞋子匹配(大小相同且方向相反),记$a_{x}$表示第x双鞋子的左位置,$b_{x}$表示右位置 若$a_{x}>b_{x}$,那么可以交换这两双鞋子并令答案+1,所以不妨设$a_{ ...
- hdu 4451 Dressing 排列组合/水题
Dressing Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Subm ...
- 学习sql中的排列组合,在园子里搜着看于是。。。
学习sql中的排列组合,在园子里搜着看,看到篇文章,于是自己(新手)用了最最原始的sql去写出来: --需求----B, C, F, M and S住在一座房子的不同楼层.--B 不住顶层.C 不住底 ...
- [LeetCode] Arranging Coins 排列硬币
You have a total of n coins that you want to form in a staircase shape, where every k-th row must ha ...
- [LeetCode] Next Permutation 下一个排列
Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...
- js学习篇--数组按升序降序排列
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- SDOI 2016 排列计数
题目大意:一个数列A,n个元素,其中m个元素不动,其他元素均不在相应位置,问有多少种排列 保证m个元素不动,组合数学直接计算,剩余元素错位排列一下即可 #include<bits/stdc++. ...
- 排列组合算法的javascript实现
命题:从成员数为N的集合S中,选出M个元素,分别求其排列与组合结果集,即 A(N, M)与C(N, M) js解法: function queue(arr, size){ if(size > a ...
- 剑指Offer面试题:26.字符串的排列
一.题目:字符串的排列 题目:输入一个字符串,打印出该字符串中字符的所有排列.例如输入字符串abc,则打印出由字符a.b.c所能排列出来的所有字符串abc.acb.bac.bca.cab和cba. 二 ...
随机推荐
- OpenCV开发笔记(八十三):图像remap实现哈哈镜效果
前言 对图像进行非规则的扭曲,实现哈哈镜就是一种非常规的扭曲方式,本文先描述remap的原理,然后通过remap实现哈哈镜. Demo 基于原始算法,可以进行二次开发 ...
- Grafana导入 json 文件的 dashboard 错误 Templating Failed to upgrade legacy queries Datasource xxx not found
前言 编辑或者修改后的 dashboard 保存为 json 文件,在其他环境导入使用,报错 Failed to upgrade legacy queries Datasource xxxxxxx w ...
- 如何通过 MCP 将你的 Supabase 数据库连接到 Cursor
Cursor + MCP + Supabase. 图片来自作者 在过去几周里,MCP(Model Context Protocol,模型上下文协议)在许多 AI 相关的在线社区和论坛里大火.开发者和技 ...
- Oracle12c 数据库 警告日志
目录 一:查看警告日志文件的位置 二:警告日志内容 三:告警日志监控: 方案1: 方案2: 方案3: 正文 回到顶部 一:查看警告日志文件的位置 Oracle 12c环境下查询,alert日志并不在b ...
- Linux性能分析-平均负载
平均负载的理解 一般系统变慢时,我们会使用top或uptime命令来查看下系统的负载情况 [root@localhost shell]# uptime 13:51:08 up 5 days, 21:5 ...
- 学习unigui【25】关于图标
网上有不少介绍. 自己的经验: 是否需要下载文件fontawesome-free-6.5.1-web(),没有研究.说ext_js已经下载配套了. 我很懒,得过且过. 1.下载fontawesome- ...
- study Rust-1【Rust的特点和应用场景】
Rust语言的特点 高性能 - Rust 速度惊人且内存利用率极高.由于没有运行时和垃圾回收,它能够胜任对性能要求特别高的服务,可以在嵌入式设备上运行,还能轻松和其他语言集成. 可靠性 - Rust ...
- FMM4在XE下使用
在project中增加 {$IFDEF DEBUG} ReportMemoryLeaksOnShutdown := True; {$ENDIF} 即可得到提示,如果内存有泄漏的话.但是想进一步仔细使用 ...
- zk基础—1.一致性原理和算法
大纲 1.分布式系统特点 2.分布式系统的理论 3.两阶段提交Two-Phase Commit(2PC) 4.三阶段提交Three-Phase Commit(3PC) 5.Paxos岛的故事来对应Zo ...
- 11. RabbitMQ 消息队列 Federation (Exchange 交换机和 Queue队列) + Shovel 同步的搭建配置
11. RabbitMQ 消息队列 Federation (Exchange 交换机和 Queue队列) + Shovel 同步的搭建配置 @ 目录 11. RabbitMQ 消息队列 Federat ...