列表

详情


OR162. 链式边权

描述

n个点连成一条链,从左往右依次从1n编号。相邻点之间有边相连,一共有n-1条边。所有的边从1n-1编号,第i条边连接了点ii+1

i个点有点权ai,定义第i条边的权重为wi:有多少点对xy满足在第i条边的左侧(x≤i),y在第i条边的右侧(y>i),且xy的点权不同。

给出每个点的点权,请求出所有边的边权。

输入描述

第一行输入一个数n。(2≤n≤100000)

第二行输入n个数,a1,a2,…,an (1≤ai≤109)

输出描述

输出n-1个数,依次为每条边的权重,不要在行末输出多余的空格。

示例1

输入:

3
1 2 1

输出:

1 1

原站题解

C++ 解法, 执行用时: 55ms, 内存消耗: 10012KB, 提交时间: 2020-10-31

#include <cstdio>
#include <unordered_map>
using namespace std;
  
int nums[100005];
  
void solve(int n) {
    long long pre = 0;
    unordered_map<int, int> left, rite;
    for (int i = n - 1; i >= 0; --i)
        rite[nums[i]]++;
    for (int i = 0; i < n - 1; ++i) {
        printf("%lld%c", pre += n - 2 * i - rite[nums[i]] + left[nums[i]], i == n - 2 ? '\n' : ' ');
        rite[nums[i]]--;
        left[nums[i]]++;
    }
}
  
int main() {
    int n, i = 0;
    for (scanf("%d", &n); i < n; ++i)
        scanf("%d", nums + i);
    solve(n);
}

C++ 解法, 执行用时: 60ms, 内存消耗: 10012KB, 提交时间: 2020-10-31

#include <cstdio>
#include <unordered_map>
using namespace std;
  
int nums[100005];
  
void solve(int n) {
    long long pre = 0;
    unordered_map<int, int> left, rite;
    for (int i = n - 1; i >= 0; --i)
        rite[nums[i]]++;
    for (int i = 0; i < n - 1; ++i) {
        printf("%lld%c", pre += n - 2 * i - rite[nums[i]] + left[nums[i]], i == n - 2 ? '\n' : ' ');
        rite[nums[i]]--;
        left[nums[i]]++;
    }
}
  
int main() {
    int n, i = 0;
    for (scanf("%d", &n); i < n; ++i)
        scanf("%d", nums + i);
    solve(n);
}

上一题