[USACO 2018 US Open Platinum]Out of Sorts 排序模拟

    科技2024-11-29  13

    文章目录

    一.题目二.Solution三.CodeThanks!

    一.题目

    传送门

    二.Solution

    这道题目主要是理解题目,题目中冒泡排序到底是怎么排的?其实就是从第一个数开始将其交换到最后一个比它小的数的位置,将这期间的长度累加就是答案了。 考虑什么时候排序完成,就是每个数之间都有一个分隔点出现的时候就排序完成了。我们将 i i i i + 1 i+1 i+1之间的分隔点保存在 i i i点上,用 t [ i ] t[i] t[i]数组表示分隔点 i i i出现的时间,当且仅当一个点两边都出现了分隔点时排序结束,所以每个点的答案就是 m a x ( t [ i ] , t [ i + 1 ] ) max(t[i], t[i+1]) max(t[i],t[i+1])。 考虑怎么求? 先离散化数组,处理每个数最远的比他小的数和他的距离,这个可以用单调队列等,但我没用,直接用一个变量存比当前数小的最远位置,直接减当前数的位置就行了。

    三.Code

    #include <cstdio> #include <cstring> #include <iostream> #include <map> #include <algorithm> using namespace std; #define M 100005 #define LL long long struct node { int v, id; }a[M]; int n; LL ans, t[M]; bool cmp (node a, node b){ if (a.v == b.v) return a.id < b.id; return a.v < b.v; } int main (){ scanf ("%d", &n); for (int i = 1; i <= n; i ++){ scanf ("%d", &a[i].v); a[i].id = i; } sort (a + 1, a + 1 + n, cmp); int maxn = 0; for (int i = 1; i <= n; i ++){ maxn = max (maxn, a[i].id); t[i] = max (1, maxn - i); } for (int i = 1; i <= n; i ++) ans += max (t[i], t[i - 1]); printf ("%lld\n", ans); return 0; }

    Thanks!

    Processed: 0.043, SQL: 8