首页 > 其他分享 >P1908 逆序对

P1908 逆序对

时间:2024-04-13 13:34:25浏览次数:13  
标签:bg P1908 ll mid long while 500005 逆序

原题链接

题解

本质:求一个数前面有几个数大于它,我们把序列分成几段,然后对每段分别进行排序,然后找出这个数在前面已经排好序中的序列里有几个大于它

code

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

#define ll long long

ll a[500005], b[500005], c[500005]; // a-original, b-replace, c-new
ll ans = 0;

inline void read(ll &x) {
    x = 0;
    ll flag = 1;
    char c = getchar();
    while(c < '0' || c > '9'){
        if(c == '-')flag = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9') {
        x = (x << 3) + (x << 1) + (c ^ 48);
        c = getchar();
    }
    x *= flag;
}

inline void write(ll x)
{
    if(x < 0){
        putchar('-');
        x = -x;
    }
    if(x > 9)
        write(x / 10);
    putchar(x % 10 + '0');
}

void bg(ll l, ll r)
{

    if (l == r) return;
    ll mid = (l + r) / 2;

    bg(l, mid);
    bg(mid + 1, r);
    ll p1 = l, p2 = mid + 1, p3 = l;
    while (p1 <= mid && p2 <= r)
    {
        if (c[p1] <= c[p2]) b[p3++] = c[p1++];//为什么要等于?因为等于不算逆序对
        else
        {
            b[p3++] = c[p2++];
            ans += mid - p1 + 1;
        }
    }
    while (p1 <= mid) b[p3++] = c[p1++];
    while (p2 <= r) b[p3++] = c[p2++];

    for (ll i = l; i <= r; i++) c[i] = b[i];
    return;
}

int main()
{
    ll n;
    read(n);

    for (ll i = 1; i <= n; i++)
    {
        read(a[i]);
        c[i]=a[i];
    }

    bg(1, n);
    write(ans);
    return 0;
}

标签:bg,P1908,ll,mid,long,while,500005,逆序
From: https://www.cnblogs.com/pure4knowledge/p/18132744

相关文章

  • 归并排序 返回逆序数 python
    defmerge_sort_and_count_inversions(arr):n=len(arr)ifn<=1:returnarr,0#如果n小于等于1,数组已经有序,直接返回数组本身和逆序数0mid=n//2left_lst,inv_left=merge_sort_and_count_inversions(arr[:mid])#对左半部分进行递......
  • c语言字符串逆序-基础知识
    c语言字符串逆序(1)错误输出(2)正确输出:方法1(3)正确输出:方法2......
  • 逆序并查集
    以L2-013红色警报为例原题链接https://pintia.cn/problem-sets/994805046380707840/exam/problems/994805063963230208?type=7&page=1下面贴上代码#include<iostream>usingnamespacestd;constintN=510;intp[N],g[N][N];intfind(intx){if(x!=p......
  • CF746 期望+逆序对
    Link题意:给定一个\(1\)到\(n\)的排列,等概率选一段区间\([l,r]\)随机排序,求期望逆序对数。\[E=\dfrac{\sum(cnt_{[1,n]}-cnt_{[l,r]}+E_{len})}{\dfrac{n\times(n+1)}{2}}\]\(cnt_{[l,r]}\)表示原序列\([l,r]\)内部逆序对数。\(E_{len}\)表示长度为......
  • 字符串逆序
    文章目录一、字符串?二、思路三、运行代码 一、字符串?在C语言中,字符串实际上是使用空字符 \0 结尾的一维字符数组。因此,\0 是用于标记字符串的结束。二、思路从左++和右--到中间。赋值最左边和最右边给指针left、right,然后通过left++、right--进行逆序。......
  • 随机逆序对 题解
    题意给定$1\simn$的排列$a_{1...n}$。在上面进行依次如下操作:首先在$[1,n]$​中选取一个子序列(可以为空);然后将这个子序列内的数重新排列。两个操作不同,当且仅当选取的子序列不同或者重新排列的方式不同。对于所有不同的操作,求他们产生的排列的逆序对个数和,答案......
  • abc284F 前缀+逆序+后缀
    题面:给一个长度为2n的字符串T,问是否存在长度为n的字符串S,满足:T=S的前缀+整串S逆序+S的后缀。范围:n<=1e6思路:字符串哈希,枚举S的起点逐一判断,如果前i个字符加后n-i个字符组成的长为n的字符串,正好和中间串的逆序相同,则为解。#include<bits/stdc++.h>usingnamespacestd;......
  • 从CF1676H2看逆序对的两种求法
    Problem-1676H2-Codeforces思路原问题可以以直接转化成求\(a_i>=a_j(i<j)\)的数量。归并排序原理很直接,归并排序就是为了减少逆序对的数量,所以直接在操作的时候记录减少的数量即可排序后的数组无逆序对,归并排序的合并操作中,每次后段首元素被作为当前最小值取出时......
  • 小苯的逆序对
    小苯的逆序对题目描述小苯有一个长度为$n$的排列$p$。他很想知道这个排列中有多少个逆序对满足互素。形式化的,有多少个满足$(i<j)$且$(a_i>a_j)$且$gcd(a_i,a_j)=1$的$(i,j)$对。输入描述:输入包含两行。第一行一个正整数$n(1\leqn\leq2\times10^5)$......
  • P3157 [CQOI2011] 动态逆序对 题解
    题目链接:动态逆序对常见经典题,理解一个数对逆序对贡献计算即可。对于一个数而言,它在一个序列中的逆序对有两部分贡献,一部分为前面比它严格大的数,另一部分为后面比它严格小的数,有道二莫题也是基于此去考虑的。考虑最开始知道了总逆序数,每次删除一个数逆序数会减少两部分值,显然就......