首页 > 其他分享 >CF1637H Minimize Inversions Number

CF1637H Minimize Inversions Number

时间:2022-11-25 19:45:21浏览次数:46  
标签:ch Minimize inv Number int 那么 序列 Inversions sum

Minimize Inversions Number

首先考虑\(k = 1\),记\(g_i = \sum_{j = 1}^{i - 1} [p_i < p_j] - \sum_{j = 1}^{i - 1} [p_i > p_j]\),那么\(g_i\)表示将\(i\)移向最前面逆序对减少的量,那么我们的就相当于求\(\max g_i\)。
在考虑\(k > 1\),我们选择一个子序列\(a_1, a_2, ... ,a_k\),如果我们每次把最左的数移到序列最前,那么我们的贡献就为\(\sum g_{a_i}\),但这样移到最前面的子序列就反转了,所以我们应该,再将其反转回来,记\(inv\)为子序列的逆序对个数,那么贡献应加上\(2 * inv - \dbinom{k}{2}\),但我们很难去动态维护\(inv\),应该考虑子序列的特殊性质。
一个结论对于\(i < j, p_i > p_j\),\(j\)选在子序列中一定不劣。
证明:考虑一个离\(i\)最近的\(j\),那么一定不存在\(i < k < j\)使得\(p_k < p_j < p_i\),那么把\(j\)移到最前面贡献一定不劣于\(i\)。
那么我们的\(inv\)就很好求了,设\(val_i\)表示将\(i\)选进子序列的贡献,那么\(val_i = g_i - 2 \sum_{j = i + 1}^n[p_i > p_j]\)。
把\(val_i\)排序,一个一个加入答案即可。
用树状数组维护,时间复杂度为\(O(n \log n)\)。

Code
#include<cstdio>
#include<iostream>
#include<algorithm>
#define IN inline
#define LL long long
using namespace std;
const int N = 5e5 + 5;
int n, a[N], T; LL f[N], g[N];

IN int read() {
	int t = 0,res = 0; char ch = getchar();
	for (; !isdigit(ch); ch = getchar()) t |= (ch == '-');
	for (; isdigit(ch); ch = getchar()) res = (res << 3) + (res << 1) + (ch ^ 48);
	return t ? -res : res;
}
int lowbit(int x){return x & -x;}
void add(int x, int v){for (; x <= n; x += lowbit(x)) f[x] += v;}
LL query(int x) {
	LL res = 0;
	for (; x; x -= lowbit(x)) res += f[x];
	return res;
}
int main() {
	T = read();
	for (; T; T--) {
		n = read(); LL ans = 0;
		for (int i = 1; i <= n; i++) a[i] = read();
		for (int i = 1; i <= n; i++) 
			ans += i - 1 - query(a[i]), g[i] = (LL)(i - 1) - 2LL * query(a[i]), add(a[i], 1);
		for (int i = 1; i <= n; i++) add(a[i], -1);
		for (int i = n; i >= 1; i--) g[i] -= 2LL * query(a[i]), add(a[i], 1);
		for (int i = 1; i <= n; i++) add(a[i], -1); 
		sort(g + 1, g + 1 + n);
		for (int i = 0; i <= n; i++)
			printf("%lld ", ans - (LL)i * (i - 1) / 2), ans -= g[n - i]; puts("");
	}
}

标签:ch,Minimize,inv,Number,int,那么,序列,Inversions,sum
From: https://www.cnblogs.com/nibabadeboke/p/16926183.html

相关文章

  • POJ3252 Round Numbers
    终于一遍就写对了.第一次没有注意读题导致了一个没有注意到什时候要开始统计.Code#include<iostream>#include<string>#defineintlonglongusingnamespacestd;......
  • [数学记录][sosdp]CF449D Jzzhu and Numbers
    前几天做arc时连做两道高维前缀和,今天去看dp题单时发现这东西居然叫sosdp,来刷一下板子。粘一篇找到的blog,感觉引入那里非常自然!linktoCF|linktoLuogu给......
  • SQL Server 中 Rank、row_number、dense_rank 三种排序函数的区别
    现有一张工资表,需要对其进行排名,工资相同的人并列排名,然后再排名,很多刚接触的小伙伴估计第一时间想到Rank()函数或row_number() 函数,但是结果出来后并不是自己想要的,在......
  • HDU3652 B-number
    Idea数位DP.注意加一点记录.第一次写的时候把\(i\)写成了1,调整了好久,第二个错误是没注意到13是要连续的.因此Code可以再简化.Code#include<bits/stdc++.h>usin......
  • 200. Number of Islands
    Givenan mxn 2Dbinarygrid grid whichrepresentsamapof '1's(land)and '0's(water),return thenumberofislands.An island issurroundedbywa......
  • codeforce E - Binary Inversions题解
    题目:给你一个01串,现在你可以(或者不用)选取其中一个元素进行一次反转操作0-1,1-0;从而使得串中的逆序对个数最多。题目链接:codeforceoriginproblem思路:1.如何统计逆序对......
  • [LeetCode] 795. Number of Subarrays with Bounded Maximum
    Givenanintegerarray nums andtwointegers left and right,return thenumberofcontiguousnon-empty subarrays suchthatthevalueofthemaximumarr......
  • 动态规划- [USACO1.5][IOI1994]数字三角形 Number Triangles
    [USACO1.5][IOI1994]数字三角形NumberTriangles题目描述观察下面的数字金字塔。写一个程序来查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每一步可以......
  • [LeetCode] 2133. Check if Every Row and Column Contains All Numbers
    An nxn matrixis valid ifeveryrowandeverycolumncontains all theintegersfrom 1 to n (inclusive).Givenan nxn integermatrix matrix,re......
  • POJ2104-K-th Number(浅析主席树)
    K-thNumberTimeLimit: 20000MS MemoryLimit: 65536KTotalSubmissions: 65162 Accepted: 22979CaseTimeLimit: 2000MSDescriptionYouareworkingforMac......