[NOI Online 2022 提高组] 如何正确地排序
\(\text{Solution}\)
当 \(m=2\) 时,\(ans=2n\sum a_{i,j}\)
当 \(m=3\) 时
当然先套路地考虑某一行的贡献,记为第 \(x\) 行
则当取 \(max\) 时有 \(a_{x,i}+a_{x,j}>a_{y,i}+a_{y,j},a_{x,i}+a_{x,j}>a_{z,i}+a_{z,j}\)
即 \(a_{x,i}-a_{y,i}>a_{y,j}-a_{x,j},a_{x,i}-a_{z,i}>a_{z,j}-a_{x,j}\)
把第 \(i\) 列看作二元组 \((a_{y,j}-a_{x,j},a_{z,j}-a_{x,j})\),询问则是 \(<(a_{x,i}-a_{y,i},a_{x,i}-a_{z,i})\) 的数量
二位偏序,树状数组即可
当 \(m=4\) 时,可以同 \(m=3\) 那样,三位偏序 \(cdq\) 分治
当然 \(\text{Min-max}\) 容斥更妙,因为
\]
\(\max\) 同理
把 \(\min+\max\) 展开,则可以发现 \(2ans=\sum_{T\subseteq S} (-1)^{|T|-1} \max_{i\in T} x_i + \min_{i\in T} x_i\)
于是沿用 \(m=2\) 和 \(m=3\) 的做法即可
注意到这里用了严格大于小于符号,但需要考虑取等,这东西很容易算重
一个笨点的方法就是当不等式相等时,默认 \(x<y\) 的更小,\(x<z\) 的更小,将贡献放到最早的有相等的行
这需要在修改和查询时讨论相等情况
\(\text{Code}\)
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#define RE register
#define IN inline
using namespace std;
typedef long long LL;
const int N = 2e5 + 5, len = 4e5 + 7, D = 2e5 + 3;
int m, n, a[5][N];
LL SUM, ans;
IN void read(int &x)
{
char ch = getchar(); x = 0; int f = 1;
for(; !isdigit(ch); f = (ch == '-' ? -1 : 1), ch = getchar());
for(; isdigit(ch); x = (x<<3)+(x<<1)+(ch^48), ch = getchar());
x *= f;
}
struct node{
int ty, x, y, v;
IN bool operator < (const node &a) const{return x < a.x ? 1 : (x == a.x ? ty < a.ty : 0);}
}Q[N * 2];
struct BIT{
int c[len + 3];
IN void init(){memset(c, 0, sizeof c);}
IN int lowbit(int x){return x & (-x);}
IN void add(int x){x += D; for(; x <= len; x += lowbit(x)) c[x]++;}
IN int Query(int x){x += D; int s = 0; for(; x; x -= lowbit(x)) s += c[x]; return s;}
}T;
IN LL calc(int x, int y, int z)
{
int cnt = 0; LL res = 0;
for(RE int i = 1; i <= n; i++)
Q[++cnt] = node{1, a[y][i] - a[x][i], a[z][i] - a[x][i]},
Q[++cnt] = node{0, a[x][i] - a[y][i], a[x][i] - a[z][i], a[x][i]};
sort(Q + 1, Q + cnt + 1);
for(RE int i = 1, j; i <= cnt; i = j + 1)
{
j = i;
while (j < cnt && Q[j + 1].x == Q[i].x) ++j;
if (x < y) for(RE int k = j; k >= i; k--) if (Q[k].ty) T.add(Q[k].y);
else res += (LL)Q[k].v * T.Query(Q[k].y - 1 + (x < z));
else for(RE int k = i; k <= j; k++) if (Q[k].ty) T.add(Q[k].y);
else res += (LL)Q[k].v * T.Query(Q[k].y - 1 + (x < z));
}
T.init();
for(RE int i = cnt, j; i; i = j - 1)
{
j = i;
while (j > 1 && Q[j - 1].x == Q[i].x) --j;
if (x < y) for(RE int k = i; k >= j; k--) if (Q[k].ty) T.add(Q[k].y);
else res += (LL)Q[k].v * (T.Query(len - D) - T.Query(Q[k].y - (x < z)));
else for(RE int k = j; k <= i; k++) if (Q[k].ty) T.add(Q[k].y);
else res += (LL)Q[k].v * (T.Query(len - D) - T.Query(Q[k].y - (x < z)));
}
T.init();
return res * 2;
}
IN LL solve3(int i, int j, int k){return calc(i, j, k) + calc(j, i, k) + calc(k, i, j);}
IN LL solve2(int i, int j)
{
LL res = 0;
for(RE int x = 1; x <= n; x++) res += a[i][x] + a[j][x];
return res * n * 2;
}
int main()
{
read(m), read(n);
for(RE int i = 0; i < m; i++)
for(RE int j = 1; j <= n; j++) read(a[i][j]), SUM += a[i][j];
if (m == 2) ans = solve2(0, 1);
else if (m == 3) ans = solve3(0, 1, 2);
else{
ans = SUM * n * 4;
for(RE int i = 0; i < 4; i++)
for(RE int j = i + 1; j < 4; j++) ans -= solve2(i, j);
for(RE int i = 0; i < 4; i++)
for(RE int j = i + 1; j < 4; j++)
for(RE int k = j + 1; k < 4; k++) ans += solve3(i, j, k);
ans >>= 1;
}
printf("%lld\n", ans);
}
[NOI Online 2022 提高组] 如何正确地排序的更多相关文章
- luogu P6570 [NOI Online #3 提高组]优秀子序列 二进制 dp
LINK:P6570 [NOI Online #3 提高组]优秀子序列 Online 2的T3 容易很多 不过出于某种原因(时间不太够 浪了 导致我连暴力的正解都没写. 容易想到 f[i][j]表示前 ...
- [NOI Online 2021 提高组] 积木小赛
思路不说了. 想起来自己打比赛的时候,没睡好.随便写了个\(HASH\),模数开小一半分都没有. 然后学了\(SAM\),发现这个判重不就是个水题. \(SAM\)是字串tire的集合体. 随便\(d ...
- [NOI Online #2 提高组]涂色游戏 题解
题目描述 你有 1020 个格子,它们从 0 开始编号,初始时所有格子都还未染色,现在你按如下规则对它们染色: 编号是 p1 倍数的格子(包括 0号格子,下同)染成红色. 编号是 p2 倍数的格子染成 ...
- NOI On Line 提高组题解
(话说其实我想填的是去年CSP的坑...但是貌似有一道题我还不会写咕咕咕... 先写一下这一次的题解吧. T1:序列.题意省略. 两种操作.这种题要先分析部分分 给出了全部都是2操作的子任务. 发现A ...
- NOI Online #2 提高组 游戏
没用二项式反演的菜比. 题目链接 Solution 非平局代表的树上祖先关系是比较好统计,(可以在处理一个点时,考虑用他去匹配他的子树中的东西)而平局的关系比较难统计.我们不妨求出至少 \(k\) 个 ...
- NOI Online #2 提高组 游记
没 NOI Online 1 挂的惨就来写游记吧,不知道为啥 NOI Online 1 民间数据测得 60 分的 T1 最后爆零了... 昏昏沉沉的醒来,吃了早饭,等到 \(8:30\) 进入比赛网页 ...
- NOI Online #3 提高组 T1水壶 题解
题目描述 有 n 个容量无穷大的水壶,它们从 1∼n 编号,初始时 i 号水壶中装有 Ai 单位的水. 你可以进行不超过 k 次操作,每次操作需要选择一个满足 1≤x≤n−1 的编号 x,然后把 x ...
- NOI Online #3 提高组 游记
考的好就来写游记吧 2020.5.24 星期日 上一天晚上为了班里事物做 PPT 肝到 11:30,这比赛就打打玩玩.第二天醒来有点昏昏沉沉的感觉. 打开题面,一看 T1,好像是个性质极其简单的前缀和 ...
- [NOI Online #3 提高组] 魔法值
现在只会\(O(qn^3log)\)的\(40pts\)做法,鸽了. 反正就是预处理之后,去掉一个\(n\). 我预处理了,没去\(n\),hhhh,成功减少了一半的常数.
- 洛谷 P6570 - [NOI Online #3 提高组] 优秀子序列(集合幂级数+多项式)
洛谷题面传送门 首先 \(3^n\) 的做法就不多说了,相信对于会状压 dp+会枚举子集的同学来说不算困难(暴论),因此这篇博客将着重讲解 \(2^nn^2\) 的做法. 首先如果我们把每个 \(a_ ...
随机推荐
- PP视频(PPTV聚力)web接口分析
前言 前几天我想看一个番剧, 正好搜索到了 PP视频,我才知道PP视频就是PPTV聚力,我想把番剧下载下来,结果发现视频竟然不是m3u8格式,而是多段mp4,所以简单的写了个脚本,可以在不登录的情况下 ...
- echarts map地图中绘制浙江省市区县乡镇多级联动边界下钻的最新geojson数据文件获取和更新
目录 ECharts Map地图的显示 GeoJSON数据文件获取 在ECharts中绘制浙江省的数据 ECharts Map地图的显示 ECharts支持地理坐标显示,专门提供了一个geo组件,在s ...
- Java工厂模式的最佳实践?
"Simplicity is prerequisite for reliability." - Edsger Dijkstra "简单是可靠的前提条件." -- ...
- Hadoop如何保证自己的江湖地位?Yarn功不可没
前言 任何计算任务的运行都离不开计算资源,比如CPU.内存等,那么如何对于计算资源的管理调度就成为了一个重点.大数据领域中的Hadoop之所以一家独大,深受市场的欢迎,和他们设计了一个通用的资源管理调 ...
- django框架(部分讲解)
ORM执行SQL语句 有时候ORM的操作效率可能偏低 我们是可以自己编写SQL的 方式1: raw()方法执行原生sql语句 models.User.objects.raw('select * fro ...
- django.core.exceptions.ImproperlyConfigured: Application labels aren't unique, duplicates: rest_framework_swagger
在启动服务时报django.core.exceptions.ImproperlyConfigured: Application labels aren't unique, duplicates: re ...
- JAVA中使用最广泛的本地缓存?Ehcache的自信从何而来2 —— Ehcache的各种项目集成与使用初体验
大家好,又见面了. 本文是笔者作为掘金技术社区签约作者的身份输出的缓存专栏系列内容,将会通过系列专题,讲清楚缓存的方方面面.如果感兴趣,欢迎关注以获取后续更新. 在上一篇文章<JAVA中使用最广 ...
- [cocos2d-x]判断两个矩形是否有交叉区域
bool Rect::intersectsRect(const Rect& rect) const { return !( getMaxX() < rect.getMinX() || r ...
- Markdown最基础语法内容
基础常用语法(大多符号后都要跟一个空格) 一.标题 1.使用 # 号可表示 1-6 级标题,一级标题对应一个 # 号,二级标题对应两个 # 号,以此类推. #不要漏了符号和内容之间的空格 一级标题 # ...
- (13)go-micro微服务公用函数开发
目录 一 前言 二 SwapTo 通过json tag 进行结构体赋值 三 UserForResponse 类型转化 四 最后 一 前言 在utils目录中新建一个swap.go文件 swap.go中 ...