首页 > 其他分享 >p1908

p1908

时间:2025-01-16 16:04:26浏览次数:3  
标签:nn p1908 int LL 序列 include 逆序

Description

猫猫 TOM 和小老鼠 JERRY 最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计。

最近,TOM 老猫查阅到一个人类称之为“逆序对”的东西,这东西是这样定义的:对于给定的一段正整数序列,逆序对就是序列中 ai>ajai​>aj​ 且 i<ji<j 的有序对。知道这概念后,他们就比赛谁先算出给定的一段正整数序列中逆序对的数目。注意序列中可能有重复数字。

Update:数据已加强。

Input

第一行,一个数 nn,表示序列中有 nn 个数。

第二行 nn 个数,表示给定的序列。序列中每个数字不超过 109109。

Output

输出序列中逆序对的数目。

Sample 1

InputcopyOutputcopy
6
5 4 2 6 3 1
11

Hint

对于 25%25% 的数据,n≤2500n≤2500。

对于 50%50% 的数据,n≤4×104n≤4×104。

对于所有数据,n≤5×105n≤5×105。

请使用较快的输入输出。

应该不会 O(n2)O(n2) 过 50 万吧 by chen_zhe。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

typedef long long LL;
const int N = 1e7 + 7; // 根据题目数据范围调整

int n, a[N], b[N];
LL sum[N << 2]; // 区间和

// 更新线段树
void change(int u, int l, int r, int x) {
    if (l == r) {
        sum[u]++;
        return;
    }
    int mid = (l + r) >> 1;
    if (x <= mid)
        change(u << 1, l, mid, x);
    else
        change(u << 1 | 1, mid + 1, r, x);
    sum[u] = sum[u << 1] + sum[u << 1 | 1];
}

// 查询线段树
LL query(int u, int l, int r, int x, int y) {
    if (x <= l && r <= y)
        return sum[u];
    int mid = (l + r) >> 1;
    LL s = 0;
    if (x <= mid)
        s += query(u << 1, l, mid, x, y);
    if (y > mid)
        s += query(u << 1 | 1, mid + 1, r, x, y);
    return s;
}

int main() {
    scanf("%d", &n);
    vector<int> vec;
    for (int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
        vec.push_back(a[i]);
    }
    sort(vec.begin(), vec.end());
    vec.erase(unique(vec.begin(), vec.end()), vec.end()); // 去重

    LL s = 0;
    for (int i = 1; i <= n; i++) {
        int id = lower_bound(vec.begin(), vec.end(), a[i]) - vec.begin() + 1;
        change(1, 1, (int)vec.size(), id);
        s += query(1, 1, (int)vec.size(), id + 1, (int)vec.size());
    }
    printf("%lld\n", s);
    return 0;
}

标签:nn,p1908,int,LL,序列,include,逆序
From: https://blog.csdn.net/2402_86997774/article/details/145184563

相关文章

  • P1908 逆序对
    题目描述猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计。最近,TOM老猫查阅到一个人类称之为“逆序对”的东西,这东西是这样定义的:对于给定的一段正整数序列,逆序对就是序列中 ai>aj​ 且 i<j的有序对......
  • 洛谷题单指南-分治与倍增-P1908 逆序对
    原题链接:https://www.luogu.com.cn/problem/P1908题意解读:求序列逆序对数。解题思路:1、暴力法对于每一个数,寻找后面有多少数比其小,或者采用冒泡排序,交换的次数即逆序对的个数,复杂度为O(n^2)2、归并排序法在归并排序过程中,会进行有序序列的合并,设两部分连续的有序序列为a[s1,......
  • P1908 逆序对
    P1908逆序对跟用树状数组求如出一辙,但是它可以不离散化直接求解,因为它可以直接把区间传到函数里,正负无所谓,反正是动态开点,此题作为动态开点的演示。这种线段树十分耗费空间。#include<iostream>usingnamespacestd;constintM=15000010,INF=1e9;//M是理论值,远远达不到int......
  • P1908 逆序对
    原题链接题解本质:求一个数前面有几个数大于它,我们把序列分成几段,然后对每段分别进行排序,然后找出这个数在前面已经排好序中的序列里有几个大于它code#include<bits/stdc++.h>usingnamespacestd;#definelllonglonglla[500005],b[500005],c[500005];//a-original......
  • P1908 逆序对
    输入格式第一行,一个数 n,表示序列中有 n个数。第二行 n 个数,表示给定的序列。序列中每个数字不超过 109109。输出格式输出序列中逆序对的数目。 依次输入n个数,输入的过程中将树状数组第a[i]加上1,统计比a[i]大的数字的个数的和,依次相加,便是逆序对的个数#include<......
  • 洛谷P1908 逆序对
    题目描述猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计。最近,TOM老猫查阅到一个人类称之为“逆序对”的东西,这东西是这样定义的:对于给定的一段正整数序列,逆序对就是序列中ai​>aj​且 i<j 的有序对。......
  • P1908 逆序对
    题目描述猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计。最近,TOM老猫查阅到一个人类称之为“逆序对”的......
  • P1908 逆序对
    逆序对题目描述猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计。最近,TOM老猫查阅到一个人类称之......