E.Power of Points
题目:
链接:https://www.luogu.com.cn/problem/CF1857E or https://codeforces.com/problemset/problem/1857/E
思路
我的思路可能比较复杂:
首先由于覆盖的是整点,那么可以想到排序后用前缀和,比如1 4 3
--> 1 3 4
然后由于区间[a,b]的整点数是b-a+1,那么该点的数量就是
注意:这里的a指的是没有加入前缀和但是排好序的原始数组,然后进行前缀和,就是
注意:这里的a是已经进行前缀和处理的结果,times是指每个元素出现的次数。
然后两个map指示的是每个位置对应的值,id_to_val和idk_to_val的作用不一样。
代码:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<sstream>
#include<string>
#include<string.h>
#include<iomanip>
#include<stdlib.h>
#include<map>
#include<queue>
#include<limits.h>
#include<climits>
#include<fstream>
#include<stack>
typedef long long ll;
using namespace std;
const int N = 2e5 + 10;
ll x[N];
struct ea
{
ll val, id; ll ans; ll timesx;
ea(){}
ea(ll v, ll i) { id = i; val = v; }
};
vector<ea>ealst;
bool cmp1(ea x,ea y)
{
return x.val < y.val;
}
bool cmp_by_id(ea x, ea y)
{
return x.id < y.id;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
ll t; cin >> t;
while (t--)
{
ealst.clear();
map<ll, ll>times;
ll n; cin >> n;
map<ll, ll >idk_to_val;
map<ll, ll>id_to_val;
map<ll, ll>val_to_ans;
for (int i = 1; i <= n; i++)
{
ll x; cin >> x;
id_to_val[ealst.size() + 1] = x;
idk_to_val[i] = x;
if (!times[x])
{
ealst.push_back(ea(x, ealst.size() + 1));
}
times[x]++;
}
sort(ealst.begin(), ealst.end(), cmp1);
vector<ea>::iterator ita;
for (vector<ea>::iterator it = ealst.begin(); it != ealst.end(); ++it)
{
if (it == ealst.begin())
{
ita = it;
it->timesx = times[id_to_val[it->id]];
it->val = it->timesx * it->val;
continue;
}
it->timesx = times[id_to_val[it->id]];
it->val = it->timesx * it->val;
it->val += ita->val;
it->timesx += ita->timesx;
ita = it;
}
for (int i = 0; i < ealst.size(); i++)
{
if (!i)
{
val_to_ans[id_to_val[ealst[i].id]] = n + (ealst[ealst.size() - 1].val - ealst[0].val - id_to_val[ealst[0].id] * (n - ealst[0].timesx)) ;
}
else
{
val_to_ans[id_to_val[ealst[i].id]]= n + (ealst[ealst.size() - 1].val - ealst[i].val - ealst[i - 1].val + id_to_val[ealst[i].id] * (ealst[i - 1].timesx - ealst[ealst.size() - 1].timesx + ealst[i].timesx));
}
}
for (int it=1;it<=n;it++)
cout << val_to_ans[idk_to_val[it]]<<' ';
cout << '\n';
}
return 0;
}
感觉码量有点大,可能是当时思路不太清晰