题目描述

有一个 \(m\times n\) 的数组 \(a_{i,j}\)。

定义:

\(f(i,j)=\min\limits_{k=1}^m(a_{k,i}+a_{k,j})+\max\limits_{k=1}^m(a_{k,i}+a_{k,j})\)

你需要求出 \(\sum\limits_{i=1}^n\sum\limits_{j=1}^nf(i,j)\)

输入格式

第一行两个正整数 \(m,n\)。

接下来 \(m\) 行,每行 \(n\) 个正整数表示 \(a_{i,j}\)。

输出格式

一行一个正整数,表示答案。

输入输出样例

输入 #1

3 5
1 7 2 2 7
9 10 4 10 3
7 7 8 10 2

输出 #1复制

564

说明/提示

【样例 1 解释】

以 \(f(3,5)\) 为例:

\(\begin{aligned}f(3,5)&=\max(a_{1,3}+a_{1,5},a_{2,3}+a_{2,5},a_{3,3}+a_{3,5})+\min(a_{1,3}+a_{1,5},a_{2,3}+a_{2,5},a_{3,3}+a_{3,5})\\&=\max(9,7,10)+\min(9,7,10)\\&=10+7\\&=17\end{aligned}\)

下面给出 \(f(i,j)\) 的数表,第 \(i\) 行第 \(j\) 列表示 \(f(i,j)\):

\(\begin{array}{|c|c|c|c|c|}\hline20&27&18&22&20\\\hline27&34&24&29&23\\\hline18&24&20&22&17\\\hline22&29&22&24&22\\\hline20&23&17&22&18\\\hline\end{array}\)

它们的和是答案 \(564\)。

统一一下,为了避免繁琐的分类讨论,我们把第一行多复制几次,填满四行。这样子答案很明显是不会变的,本来的最大值和最小值不会变。所以我们同意\(m=4\)处理。

首先我们考虑计算出一个数\(a_{i,j}\)会被计算多少次,然后乘上。但是这样子计算需要三维偏序,代码量巨大,同时容易被卡常。所以我们反着来考虑,设他在每次涉及这一列时都会被计算一次,那么总答案为\(2\times n\times sum\),sum为\(a_{i,j}\)的和。要注意\(f(i,j)\)和\(f(j,i)\)都会被计算到。

然后考虑一个数什么时候是没有贡献的,当存在$$a_i+a_j\le b_i+b_j\le c_i+c_j$$时,\(b_j\)在计算\(f(i,j)\)时没有贡献。我们可以枚举a,b,c数组然后减去b的在上面这种情况中的不合法现象。

如何计算是一个重点。首先对式子进行移项,得到$$a_i-b_i\le b_j-a_j$$

\[b_i-c_i\le c_j-b_j
\]

对于j这个位置来说,要求有多少个数是满足上面两个式子的,这很明显是一个二位偏序问题。我们把所有\(a_i-b_i\)和$ b_j-a_j$进行排序,然后遍历。如果是前者那就更新,如果是后者那就询问。题目为了帮我们卡常,很良心地把范围缩小。

其实大体就是这样了。注意其实一个不在范围里的数他也会被减去两次,设\(a<b<c<d\),在\(a,b,d\)和\(a,b,c\)两次枚举中都会减去b的不合法情况,刚好和一开始算的两倍抵消。

还有一个值得注意的地方,设\(a<b=c\),那么在\(a,b,c\)和\(a,c,b\)两次都会减去\(b,c\)的情况,然而我们需要保留一个。所以我们需要给b和c定一个大小的顺序,我这里是额定行数大的数大,在排序时做一个偏移就可以了。就是在\(a_i-b_i\)上增加上a的行数是否大于b的判断。

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int m,n,a[5][N],tr[N+N],lsh[N+N],ret,mx,mn,t;
long long sum;
struct node{
int x,y,val,z;
bool operator<(const node&n)const{
if(x!=n.x)
return x<n.x;
return z<n.z;
}
}q[N+N];
int ask(int x)
{
ret=0;
for(;x;x-=x&-x)
ret+=tr[x];
return ret;
}
void update(int x)
{
for(;x<=N+N;x+=x&-x)
tr[x]++;
}
void solve(int x,int y,int z)
{
memset(tr,0,sizeof(tr));
for(int i=1;i<=n;i++)
{
q[i<<1]=(node){a[y][i]-a[x][i],a[z][i]-a[y][i],a[y][i],1};
q[2*i-1]=(node){a[x][i]-a[y][i]+(x>y),a[y][i]-a[z][i]+(y>z),0,0};
}
sort(q+1,q+n+n+1);
for(int i=1;i<=n+n;i++)
{
if(q[i].z)
sum-=1LL*q[i].val*ask(q[i].y+N);
else
update(q[i].y+N);
}
}
int main()
{
scanf("%d%d",&m,&n);
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
scanf("%d",a[i]+j);
for(int i=m+1;i<=4;i++)
for(int j=1;j<=n;j++)
a[i][j]=a[1][j];
for(int i=1;i<=4;i++)
for(int j=1;j<=n;j++)
sum+=a[i][j];
sum=sum*n*2;
for(int i=1;i<=4;i++)
for(int j=1;j<=4;j++)
if(i!=j)
for(int k=1;k<=4;k++)
if(i!=k&&j!=k)
solve(i,j,k);
printf("%lld",sum);
return 0;
}

[NOI online2022提高C] 如何正确地排序的更多相关文章

  1. [NOI Online 2022 提高组] 如何正确地排序

    \(\text{Solution}\) 当 \(m=2\) 时,\(ans=2n\sum a_{i,j}\) 当 \(m=3\) 时 当然先套路地考虑某一行的贡献,记为第 \(x\) 行 则当取 \( ...

  2. 洛谷P1808 单词分类_NOI导刊2011提高(01) 字符串排序

    洛谷P1808 单词分类_NOI导刊2011提高(01) 题目描述 Oliver为了学好英语决定苦背单词,但很快他发现要直接记住杂乱无章的单词非常困难,他决定对单词进行分类. 两个单词可以分为一类当且 ...

  3. 算法笔记_100:蓝桥杯练习 算法提高 三个整数的排序(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 问题描述 输入三个数,比较其大小,并从大到小输出. 输入格式 一行三个整数. 输出格式 一行三个整数,从大到小排序. 样例输入 33 88 77 样 ...

  4. NOI Online 提高组 题解

    来补坑了-- 个人认为三道题难度差不多-- 还有要说一嘴,为啥我在其他网站代码都好好的,复制到 cnblogs 上 Tab 就成 8 空格了?不过也懒得改了. T1 序列 首先,遇到这种加一减一还带附 ...

  5. [NOI Online 提高组]冒泡排序

    题目 洛谷等许多 \(OJ\) 都有 思路 考试题,今日无意又做了一次 然后发现自己读错题了······ 其实询问时只要 \(k\) 轮排序后的逆序对个数并不需要真的对序列进行更改 很显然 \(k\) ...

  6. Vijos1605 NOIP2008 提高组T4 双栈排序 BFS

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - Vijos1605 题意概括 有1个1~n的排列,有2个栈,现在通过以下操作,使得出栈序列有序. 操作a 当前 ...

  7. [NOI.AC#35]string 缩点+拓扑排序

    链接 因为有交换相邻字母,因此给你字符串就相当于给你了这个字符串的所有排列 把等价的串映射到整数范围,再根据 \(m\) 种魔法连边,缩点后在 DAG 上DP即可 无耻地用了int128 #inclu ...

  8. NOI ONLINE 提高组 序列 根据性质建图

    题目链接 https://www.luogu.com.cn/problem/P6185 题意 应该不难懂,跳过 分析 说实话第一眼看到这题的时候我有点懵,真不知道怎么做,不过一看数据,还好还好,暴力能 ...

  9. 几种排序算法的学习,利用Python和C实现

    之前学过的都忘了,也没好好做过总结,现在总结一下. 时间复杂度和空间复杂度的概念: 1.空间复杂度:是程序运行所以需要的额外消耗存储空间,一般的递归算法就要有o(n)的空间复杂度了,简单说就是递归集算 ...

  10. 归并排序 & 计数排序 & 基数排序 & 冒泡排序 & 选择排序 ----> 内部排序性能比较

    2.3 归并排序 接口定义: int merge(void* data, int esize, int lpos, int dpos, int rpos, int (*compare)(const v ...

随机推荐

  1. Mysql高阶自定义排序

    Mysql高阶自定义排序 嗨,大家好,我是远码,隔三岔五给大家分享一点工作的技术总结,花费的时间不多,几分钟就行,谢谢! Mysql对我们码农来说是在熟悉不过的日常了,就不在介绍它的基础用法了,今天我 ...

  2. 使用 Rancher 安装 K8s 集群

    舞台环境 Ubuntu 22.04.2 LTS Docker 24.0.2 2GB RAM或者更多 CPU 2核心或者更多 Rancher 2.6.9 测试环境中,我准备了两台 Ubuntu 服务器, ...

  3. QA|workon env后没有进入虚拟环境,但也没有报错,但cmd可以|Python虚拟环境

    问题:pycharm的terminal执行workon env后没有进入虚拟环境,但也没有报错 但cmd可以 原因:因为pycharm的terminal用的是powershell,更改为cmd,重新打 ...

  4. 小知识:调整OCI实例的时区

    之前在随笔中<Linux (RHEL)修改时区> 介绍了时区修改方法. 默认OCI实例中,时区是GMT,在国内用看着这个时区就是很别扭的事情,于是修改时区,实测无需配置 /etc/sysc ...

  5. LeetCode 周赛上分之旅 #46 经典二分答案与质因数分解

    ️ 本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 和 BaguTree Pro 知识星球提问. 学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越 ...

  6. 解决Promise的多并发问题

    提起控制并发,大家应该不陌生,我们可以先来看看多并发,再去聊聊为什么要去控制它 多并发一般是指多个异步操作同时进行,而运行的环境中资源是有限的,短时间内过多的并发,会对所运行的环境造成很大的压力,比如 ...

  7. 位图(bitmap)原理以及实现

    大家好,我是蓝胖子,我一直相信编程是一门实践性的技术,其中算法也不例外,初学者可能往往对它可望而不可及,觉得很难,学了又忘,忘其实是由于没有真正搞懂算法的应用场景,所以我准备出一个系列,囊括我们在日常 ...

  8. 6.1 KMP算法搜索机器码

    KMP算法是一种高效的字符串匹配算法,它的核心思想是利用已经匹配成功的子串前缀的信息,避免重复匹配,从而达到提高匹配效率的目的.KMP算法的核心是构建模式串的前缀数组Next,Next数组的意义是:当 ...

  9. 算法打卡|Day4 链表part02

    Day4 链表part02 今日任务 ● 24. 两两交换链表中的节点 ● 19.删除链表的倒数第N个节点 ● 面试题 02.07. 链表相交 ● 142.环形链表II 目录 Day4 链表part0 ...

  10. IDEA2019 Debug傻瓜式上手教程

      Step Into (F7):步入,如果当前行有方法,可以进入方法内部,一般用于进入自定义方法内,不会进入官方类库的方法.   Force Step Into (Alt + Shift + F7) ...