C - Swaps 2

给定两个长度为nnn的数组A,BA, BA,B,我们可以进行若干次如下操作,使AAA变成BBB,

问我们进行多少次操作,可以将AAA变成BBB,如果无解则输出−1-1−1,否则输出最小操作次数。

容易发现,不管怎么交换ai+ia_i + iai​+i的值都是不变的,当我们要得到bib_ibi​的时候,我们一定是去找一个aj+j=bi+ia_j + j = b_i + iaj​+j=bi​+i,且jjj最小的那个点,这样可以减小操作次数,

所以可以考虑先离散化,然后用vectorvectorvector存下ai+ia_i + iai​+i的所有下标。因为每个数的下标都是会变化的,所以我们要知道AAA中每个点的真实下标。

容易发现只有原始数组中的某个数下标大于当前下标,如果这个数向前移动了,这个时候才会使得我们得数组下标变大,所以只要用数组数组存一下即可。

#include <bits/stdc++.h>using namespace std;const int N = 2e5 + 10;int a[N], b[N], c[N], sum[N], n, m;vector<int> vt[N];inline int lowbit(int x) {return x & (-x);
}void update(int x, int v) {while (x <= n) {sum[x] += v;x += lowbit(x);}
}int query(int x) {int ans = 0;while (x) {ans += sum[x];x -= lowbit(x);}return ans;
}int query(int l, int r) {return query(r) - query(l - 1);
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);scanf("%d", &n);for (int i = 1; i <= n; i++) {scanf("%d", &a[i]);c[i] = a[i] + i;}sort(c + 1, c + 1 + n);m = unique(c + 1, c + 1 + n) - (c + 1);for (int i = 1; i <= n; i++) {scanf("%d", &b[i]);int pos = lower_bound(c + 1, c + 1 + m, b[i] + i) - c;if (c[pos] != b[i] + i) {puts("-1");return 0;}b[i] = pos;vt[lower_bound(c + 1, c + 1 + m, a[i] + i) - c].push_back(i);}long long ans = 0;for (int i = 1; i <= n; i++) {if (!vt[b[i]].size()) {puts("-1");return 0;}int cur = vt[b[i]].back();ans += cur + query(cur + 1, n) - i;vt[b[i]].pop_back();update(cur, 1);}printf("%lld\n", ans);return 0;
}

C - Swaps 2(树状数组,思维)相关推荐

  1. 【树状数组 思维题】luoguP3616 富金森林公园

    树状数组.差分.前缀和.离散化 题目描述 博艾的富金森林公园里有一个长长的富金山脉,山脉是由一块块巨石并列构成的,编号从1到N.每一个巨石有一个海拔高度.而这个山脉又在一个盆地中,盆地里可能会积水,积 ...

  2. hdoj 4417 Super Mario 【树状数组 + 思维】

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  3. HDU - 5775 - Bubble Sort( 树状数组 + 思维 )

    题目链接:点击进入 题目 题意 问在给出的冒泡排序过程中,一个数到达的最右边位置与最左边位置距离差. 思路 对于一个数,位置 i ,假设右边比它小的数有 r 个,左边比它大的数有 l 个,最右边到达的 ...

  4. 牛客练习赛34 - C little w and Segment Coverage(思维、树状数组)

    title: 牛客练习赛34 - C little w and Segment Coverage(思维.树状数组) date: 2018-12-15 16:36:55 tags: [树状数组,思维] ...

  5. CDQ分治 + 树状数组 ---- C. Goodbye Souvenir(三维偏序+思维)

    题目链接 题目大意: 给定长度为nnn的数组, 定义数字XXX在[l,r][l,r][l,r]内的值为数字XXX在[l,r][l,r][l,r]内最后一次出现位置的下标减去第一次出现位置的下标 给定m ...

  6. ZOJ - 4117 BaoBao Loves Reading(树状数组求区间内不同数的个数+思维)

    题目链接:点击查看 题目大意:给出一个长度为 n 的序列,其意义为第 i 秒需要看第 a[ i ] 种书,书架上可以供应无限种书,但是书桌有容量,当书桌上的容量达到上限后,如果还想从书架上拿新书来看, ...

  7. Educational Codeforces Round 80 (Rated for Div. 2) E. Messenger Simulator 思维 + 树状数组

    传送门 文章目录 题意: 思路: 题意: 给你nnn个人,一开始位置分别为1,2,...,n1,2,...,n1,2,...,n,让后mmm个操作,每次都将某个人移动到最前面,其他人依次顺延,求每个人 ...

  8. 【HDU - 5869】Different GCD Subarray Query(思维,数学,gcd,离线处理,查询区间不同数,树状数组 或 二分RMQ)

    题干: This is a simple problem. The teacher gives Bob a list of problems about GCD (Greatest Common Di ...

  9. [HEOI2012]采花(思维 + 离线 + 树状数组)

    题目链接 分析 我只能说太妙了- 离线 + 树状数组 参考题解: 这个题要和<HH的项链>做对比: 关键就是为什么要离线处理,以及 怎么对区间进行排序和维护: [SDOI2009]HH的项 ...

  10. CF362C Insertion Sort树状数组,思维,枚举

    题意:先交换任意两个,然后只能交换相邻两个,问最少操作次数和方案. 思路:由于冒泡排序有个定理就是逆序数的个数等于最少的交换相邻元素的次数,问题就转换为了交换两个数并且使得整个数组逆序数个数最少,我们 ...

最新文章

  1. 为何把日志打印到控制台很慢?
  2. 基于排队理论的云计算模型的MATLAB仿真
  3. Android开发如何进阶?
  4. 【Android Studio安装部署系列】八、Android Studio主题皮肤更换
  5. java连接linux服务器执行shell命令(框架分析+推荐)
  6. PAT1043 输出PATest (20 分)
  7. ie8 object param没有效果_如何用php实现分页效果
  8. 695.岛屿的最大面积(026)BFS
  9. Redis(数据类型及操作指令、Java连接Redis)
  10. Day6-HTML 特殊字符-实体
  11. 实战演练:PostgreSQL在线扩容
  12. supermap iserver端口介绍
  13. 实现前后端分离的心得
  14. pandas apply lambda_一分钟一个Pandas小技巧(二)
  15. 线程与进程最通俗易懂的解释(附面试题与答案)
  16. C# 类中索引器的使用
  17. Abaqus帮助文档翻译(一)快速介绍有限元
  18. android speex 音频采样率,speex进行音频去噪
  19. 聊聊北京大部分前端从业者所面临的困境
  20. 程序员学金融-金融科普(2)-正回购

热门文章

  1. js(javascript)取得当前时间小时,分钟,秒 以及毫秒
  2. mysql之主从复制 简书_MySQL主从复制(传统)
  3. idea java8_太赞了,Intellij IDEA 竟然把 Java8 的数据流问题这么完美的解决掉了!...
  4. 软件配置管理(四)代码味道与重构
  5. ftp 断点续传 Android,Android使用FTP实现断点续传
  6. php session缓存,扫盲:php session缓存至memcached中的方法
  7. 100以内素数之和python123_python质数,水仙花数,简单猜拳游戏等
  8. 北方人的快乐。。。| 今日最佳
  9. 【资源】机器学习资料包来袭
  10. Oracle小知识总结