首页 > 其他分享 >火柴排队

火柴排队

时间:2022-09-03 11:02:05浏览次数:73  
标签:temp int 排队 list mid long 火柴 left

P1966 [NOIP2013 提高组] 火柴排队 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

  • 将两数组排序,(排序前要记录每个数对应的下标,之后会用到)
  • 排好序之后两个数组就是理想的状态(即第一个数组对应第i大的数和第二个数组对应第i大的数对其,是最优解),需要知道得到这两个状态需要移动多少次,那么以first的idx(原第一个数组的下标)为下标,值为sec的idx(原第二个数组的下标)为值的数组a,a数组的逆序对就是答案,(要交换成当前理想状态需要的最少次数)
  • 用归并排序求逆序对(就是当左边的数比右边的数值要大时,用ans累加)
#include <bits/stdc++.h>
using namespace std;
#define N 1e5
#define INF 2e9
#define MAX 100005
#define mod 99999997
#define ll long long
int ans;
void merge(long long int list[], long long int temp[], int mid, int left, int right)
{
    int left_p = left, right_p = mid + 1, t_p = left;
    while (left_p <= mid && right_p <= right)
    {
        if (list[left_p] <= list[right_p])
        {
            temp[t_p++] = list[left_p++];
        }
        else
        {
            temp[t_p++] = list[right_p++];
            ans += mid - left_p + 1;
            ans %= mod;
        }
    }
    while (left_p <= mid)
        temp[t_p++] = list[left_p++];
    while (right_p <= right)
        temp[t_p++] = list[right_p++];
    for (int i = left; i <= right; i++)
    {
        list[i] = temp[i];
    }
}
void mesort(long long int list[], long long int temp[], int n, int left, int right)
{
    if (left < right)
    {
        int mid = (left + right) >> 1;
        mesort(list, temp, n, left, mid);
        mesort(list, temp, n, mid + 1, right);
        merge(list, temp, mid, left, right);
    }
}
void merg_sort(long long int list[], int n)
{
    long long int *temp = (long long int *)malloc(sizeof(long long int) * (n + 1));
    mesort(list, temp, n, 1, n);
}
struct node
{
    int num, idx;
} first_[MAX], sec_[MAX];
ll a[MAX];
int n;
int main()
{
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &first_[i].num);
        first_[i].idx = i;
    }
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &sec_[i].num);
        sec_[i].idx = i;
    }
    sort(first_ + 1, first_ + n + 1, [](node a, node b)
         { return a.num < b.num; });
    sort(sec_ + 1, sec_ + n + 1, [](node a, node b)
         { return a.num < b.num; });
    for (int i = 1; i <= n; i++)
    {
        a[first_[i].idx] = sec_[i].idx;
    }
    merg_sort(a, n);
    cout << ans % mod << endl;
}

归并求逆序对

int ans;
void merge(long long int list[], long long int temp[], int mid, int left, int right)
{
    int left_p = left, right_p = mid + 1, t_p = left;
    while (left_p <= mid && right_p <= right)
    {
        if (list[left_p] <= list[right_p])
        {
            temp[t_p++] = list[left_p++];
        }
        else
        {
            temp[t_p++] = list[right_p++];
            ans += mid - left_p + 1;
            ans %= mod;
        }
    }
    while (left_p <= mid)
        temp[t_p++] = list[left_p++];
    while (right_p <= right)
        temp[t_p++] = list[right_p++];
    for (int i = left; i <= right; i++)
    {
        list[i] = temp[i];
    }
}
void mesort(long long int list[], long long int temp[], int n, int left, int right)
{
    if (left < right)
    {
        int mid = (left + right) >> 1;
        mesort(list, temp, n, left, mid);
        mesort(list, temp, n, mid + 1, right);
        merge(list, temp, mid, left, right);
    }
}
void merg_sort(long long int list[], int n)
{
    long long int *temp = (long long int *)malloc(sizeof(long long int) * (n + 1));
    mesort(list, temp, n, 1, n);
}

 

标签:temp,int,排队,list,mid,long,火柴,left
From: https://www.cnblogs.com/Wang-Xianyi/p/16652161.html

相关文章

  • P1966 [NOIP2013 提高组] 火柴排队做题笔记
    这题和P5677一样,是从树状数组题单里翻出来的,由于开始看时感觉题解代码写的不是很清晰,就先放进了做题计划里,后来几次看这道题,但由于第一次看题可能留下了一些心理阴影以及......
  • P1966 [NOIP2013 提高组] 火柴排队
    有两盒火柴,每盒装有\(n\)根火柴,每根火柴都有一个高度。现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同。其中\(a_i\)表示第一列火柴中第\(i\)个火柴的高......
  • 排队等候
    https://www.acwing.com/problem/content/description/1488/思路:依然核心问题是:搞经常模拟的是什么东西,如果这题模拟时间,会很烦,但模拟队列的情况,会简单很多。#include......