CodeForces 1269E K Integers solving report Fenwick tree-half reverse order

CodeForces 1269E K Integers solving report Fenwick tree-half reverse order

Problem-solving ideas: Fenwick tree, reverse order, two points. Meaning of the questions is to give a set of numbers, in turn let you ask discharge switching sequence of at least 1 to k times in the array, (k varying from 1 to n, each plus 1), at first I thought of him as a simple reverse to do in ascending order, on the wa. This question is a multi-step, multi-coupled to the numbers 1 to k of these against the price together.
Finally a little taste of the algorithm, so hard.
Here Insert Picture Description

#include<iostream>
#include<math.h>
#include<iomanip>
#include<algorithm>
#include<iostream>
#include<math.h>
#include<iomanip>
#include<algorithm>
#include<queue>
#include<cstring>
#include<string>
#include<map>
#include<stack>
#include<stdio.h>
#include<cstdio>
#include<stdlib.h>
#include<fstream>
#include<iomanip>
#pragma warning(disable:4996)
#define INF 0x3f3f3f3f
#define ll long long
#define PI acos(-1.0)
const int N = 1000010;
const int maxn = 1e9;
using namespace std;
ll a[200005];
ll sum[200005];
ll sum2[200005];
ll pos[200005];
ll n;
ll lowbit(ll x)
{
	return x &(-x);
}
void add(ll sum[], ll x, ll v)
{
	while (x <= n)
	{
		sum[x] += v;
		x += lowbit(x);
	}
}
ll query(ll sum[], ll x)
{
	ll res = 0;
	while (x > 0)
	{
		res += sum[x];
		x -= lowbit(x);
	}
	return res;
}
int main()
{
	scanf("%lld", &n);
	for (int i = 1; i <= n; i++)
	{
		scanf("%lld", &a[i]);
		pos[a[i]] = i;//记录每个数的初始下标,即在数组中的位置
	}
	ll ansl = 0;
	for (int i = 1; i <= n; i++)
	{
		ansl += i - 1 - query(sum, pos[i]);//这里求逆序对
		add(sum, pos[i], 1);//这棵树用来求逆序对
		add(sum2, pos[i], pos[i]);//这棵树用来求将数靠在一起需要的代价
		ll mid;
		ll l = 1, r = n;
		while (l <= r)
		{
			mid = (l + r) >> 1;
			if (query(sum, mid) * 2 <= i)
			{
				l = mid + 1;
			}
			else
			{
				r = mid - 1;
			}
		}
		ll ansr = 0;//这里求将1到k的数靠在一起需要的代价
		ll cnt = query(sum, mid), all = query(sum2, mid);
		ansr += mid * cnt - all - cnt * (cnt - 1) / 2;
		cnt = i - cnt, all = query(sum2, n) - all;
		ansr += all - cnt * (mid + 1) - cnt * (cnt - 1) / 2;
		printf("%lld ", ansl + ansr);
	}
}



Published 64 original articles · won praise 0 · Views 1458

Guess you like

Origin blog.csdn.net/weixin_45566331/article/details/104527409