Codeforces Round 918 (Div. 4) F.Greetings题解

本文介绍了一个问题,即在数轴上,n个人从不同位置以相同速度移动,当两人相遇时会互相打招呼。通过先对起点排序并计算终点大于等于相遇点的人数,利用逆序对的方法得出总的问候次数。代码展示了如何使用C++的merge_sort算法解决此问题。
摘要由CSDN通过智能技术生成

Greetings

题意:数轴上有n个人;第i个人位于ai的位置。每个人的起点和终点都是不同的。)
所有人员将以每秒 前进1个单位的速度行进。当两个人在同一地点相遇时,他们会互相打招呼。会有多少问候?

请注意,即使已经到达终点,一个人仍然可以向其他人打招呼。

思路:将所有人的起点按照从小到大进行排序,这样就满足了后面的人不会撞到前面的人(只存在后面的人已经到达终点了,然后被前面的人撞)。然后再考虑能够撞多少个人:对于排完序以后的第i个人而言,他能撞到的人是i以后的,终点小于等于bi的人。因此也就是(bi>bj)且(i < j)的个数,也就是按照起点排完序之后的b数组的逆序对数量。

#include <bits/stdc++.h>
using namespace std;
#define int  long long

const int N = 5e5 + 10;
int cnt, tem[N], a[N];
pair<int, int> f[N];

int merge_sort(int arr[], int l, int r)
{
    if (l >= r)
        return 0;
    int mid = l + r >> 1, k = 0;
    int i = l, j = mid + 1;
    int sum = merge_sort(arr, l, mid) + merge_sort(arr, mid + 1, r);

    while (i <= mid && j <= r)
    {
        if (arr[i] <= arr[j])
            tem[k++] = arr[i++];
        else
        {
            tem[k++] = arr[j++];
            sum += mid - i + 1;
        }
    }

    while (i <= mid)
        tem[k++] = arr[i++];
    while (j <= r)
        tem[k++] = arr[j++];
    for (int i = l, j = 0; i <= r; j++, i++)
        arr[i] = tem[j];
    return sum;
}

signed main()
{

    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cout.precision(10);

    int t, n;
    cin >> t;
    while (t--)
    {
        cin >> n;
        for (int i = 0; i < n; i++)
            cin >> f[i].first >> f[i].second;
        sort(f, f + n);

        for (int i = 0; i < n; i++)
            a[i] = f[i].second;
        cnt = merge_sort(a, 0, n - 1);
        cout << cnt << endl;
    }
}

注意一定要关闭同步流!
一定要开long long!
一定要把数组N开大一些,本人在做题的时候开1e5+5一直爆,改成5e5+5就通过了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值