AtCoder Beginner Contest 261 F // 树状数组
题目链接:F - Sorting Color Balls (atcoder.jp)
题意:
有n个球,球有颜色和数字。对相邻的两球进行交换时,若颜色不同,需要花费1的代价。求将球排成数字不降的顺序,所需的最小代价。
思路:
将完成排序所需的最小代价记作 cost,将颜色不同的逆序对( i < j && xi > xj && ci ≠ cj )数量记作 cnt ,则有 cost = cnt。证明如下:
可以构造出一种所需花费为 cnt 的排序方案:将这n个球按颜色切分,即切分成若干个颜色相同的连续区间,那么将每个区间进行排序,不需要花费任何代价,然后再进行冒泡排序,则花费代价恰为 cnt。因此有 cost ≧ cnt 。
再证明 cost ≤ cnt :依然先将各个颜色相同的连续区间进行排序,那么不考虑颜色时,总的逆序对变为 cnt 。每次进行相邻数交换,则逆序对数量的变化可能为:+1、0、-1,那么要让逆序对数量变为 0,至少需要 cnt 次交换,因此有 cost ≤ cnt。
那么只需要求出 cnt:求出不考虑颜色时逆序对数量 totalCnt,在求出对于各个颜色,颜色相同的逆序对数量Cnti,因此:cnt = totalCnt - ∑Cnti 。
然后求逆序对,就是树状数组的经典应用了。
代码:
#include <bits/stdc++.h>
#define LL long long
#define lowbit(x) (x & -x)
using namespace std; const int N = 300010; int n, c[N];
vector<int> v[N];
int tr[N]; void add(int x, int c)
{
for(int i = x; i <= n; i += lowbit(i)) tr[i] += c;
} LL sum(int x)
{
LL res = 0;
for(int i = x; i; i -= lowbit(i)) res += tr[i];
return res;
} int main()
{
cin >> n;
for(int i = 1; i <= n; i++) scanf("%d", &c[i]);
for(int i = 1; i <= n; i++) {
int x;
scanf("%d", &x);
v[0].push_back(x); //v[0]存储不考虑颜色时的值,后续求出不考虑颜色时的逆序对
v[c[i]].push_back(x); //v[ci]则存储考虑颜色时的值,后续求出相同颜色下的逆序对
} LL ans = 0;
for(int i = 0; i <= n; i++) {
for(auto& x : v[i]) {
ans = ans + (i ? -1 : 1) * (sum(n) - sum(x));
add(x, 1);
}
for(auto& x : v[i]) add(x, -1);
}
cout << ans << endl; return 0;
}
AtCoder Beginner Contest 261 F // 树状数组的更多相关文章
- AtCoder Beginner Contest 137 F
AtCoder Beginner Contest 137 F 数论鬼题(虽然不算特别数论) 希望你在浏览这篇题解前已经知道了费马小定理 利用用费马小定理构造函数\(g(x)=(x-i)^{P-1}\) ...
- AtCoder Beginner Contest 253 F - Operations on a Matrix // 树状数组
题目传送门:F - Operations on a Matrix (atcoder.jp) 题意: 给一个N*M大小的零矩阵,以及Q次操作.操作1(l,r,x):对于 [l,r] 区间内的每列都加上x ...
- AtCoder Beginner Contest 171-175 F
171 F - Strivore 直接把初始字符当成隔板,统计的方案数会有重复 为了避免重复情况,规定隔板字母尽可能最后出现,即在隔板字母后面不能插入含隔板字母的字符串 所以在隔板字母后插入的字符只有 ...
- AtCoder Beginner Contest 133 F Colorful Tree
Colorful Tree 思路: 如果强制在线的化可以用树链剖分. 但这道题不强制在线,那么就可以将询问进行差分,最后dfs时再计算每个答案的修改值, 只要维护两个数组就可以了,分别表示根节点到当前 ...
- AtCoder Beginner Contest 260 F - Find 4-cycle
题目传送门:F - Find 4-cycle (atcoder.jp) 题意: 给定一个无向图,其包含了S.T两个独立点集(即S.T内部间的任意两点之间不存在边),再给出图中的M条边(S中的点与T中的 ...
- AtCoder Beginner Contest 213 F题 题解
F - Common Prefixes 该题也是囤了好久的题目了,看题目公共前缀,再扫一眼题目,嗯求每个后缀与其他后缀的公共前缀的和,那不就是后缀数组吗?对于这类问题后缀数组可是相当在行的. 我们用后 ...
- AtCoder Beginner Contest 249 F - Ignore Operations // 贪心 + 大根堆
传送门:F - Keep Connect (atcoder.jp) 题意: 给定长度为N的操作(ti,yi). 给定初值为0的x,对其进行操作:当t为1时,将x替换为y:当t为2时,将x加上y. 最多 ...
- AtCoder Beginner Contest 247 F - Cards // dp + 并查集
原题链接:F - Cards (atcoder.jp) 题意: 给定N张牌,每张牌正反面各有一个数,所有牌的正面.反面分别构成大小为N的排列P,Q. 求有多少种摆放方式,使得N张牌朝上的数字构成一个1 ...
- AtCoder Beginner Contest 143 F - Distinct Numbers
题意 给出一个长度为NNN的序列,求对于所有k∈[1,N]k\in[1,N]k∈[1,N],每次从序列中选出kkk个互不相同的数,最多能取多少次. N≤3e5N\le3e5N≤3e5 题解 我们首先把 ...
随机推荐
- 【mq】从零开始实现 mq-06-消费者心跳检测 heartbeat
前景回顾 [mq]从零开始实现 mq-01-生产者.消费者启动 [mq]从零开始实现 mq-02-如何实现生产者调用消费者? [mq]从零开始实现 mq-03-引入 broker 中间人 [mq]从零 ...
- 在GO中调用C源代码#基础篇1
开坑说明 最近在编写客户端程序或与其他部门做功能集成时多次碰到了跨语言的sdk集成,虽说方案很多诸如rpc啊,管道啊,文件io啊,unix socket啊之类的不要太多,但最完美的基础方式还是让程序与 ...
- tomcat 1.2 负载均衡
实验效果:访问同一个ip或域名,轮询显示两个不同的tomcat界面, nginx服务器ip:192.168.213.4 tomcat服务器ip:192.168.213.3 实验环境:两台服 ...
- 基于SqlSugar的开发框架循序渐进介绍(5)-- 在服务层使用接口注入方式实现IOC控制反转
在前面随笔,我们介绍过这个基于SqlSugar的开发框架,我们区分Interface.Modal.Service三个目录来放置不同的内容,其中Modal是SqlSugar的映射实体,Interface ...
- 《回炉重造 Java 基础》——集合(容器)
整体框架 绿色代表接口/抽象类:蓝色代表类. 主要由两大接口组成,一个是「Collection」接口,另一个是「Map」接口. 前言 以前刚开始学习「集合」的时候,由于没有好好预习,也没有学好基础知识 ...
- Spring Ioc源码分析系列--自动注入循环依赖的处理
Spring Ioc源码分析系列--自动注入循环依赖的处理 前言 前面的文章Spring Ioc源码分析系列--Bean实例化过程(二)在讲解到Spring创建bean出现循环依赖的时候并没有深入去分 ...
- Linux文本搜索及截取操作
Linux文本搜索及截取操作 cat 查看 grep 搜索 awk 截取 查看dna-server.xml 文件的内容 [root@localhost servers]# cat cwag9002/w ...
- ES6 伪数组转真数组
更新日志 2022年6月13日 发布. 2022年5月19日 笔记迁移到博客. 直接上代码 [...a];
- 解决Windows微软账户无法登录
更新记录 2022年4月16日:本文迁移自Panda666原博客,原发布时间:2021年8月25日. 将DNS的服务器地址修改为4.2.2.1或者4.2.2.2就可以解决无法登录microsoft账户 ...
- 网心云在PVE下三种磁盘IO模式(No cache,Write through,Write back)选择与优化指南
---------------------------------------------------------------------------------------------------- ...