博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
P1908 逆序对(树状数组)
阅读量:705 次
发布时间:2019-03-21

本文共 1408 字,大约阅读时间需要 4 分钟。

对于逆序对,可以用树状数组来求,而树状数组就是求出所有的非逆序对,答案当然就是所有情况减去非逆序对了。
举个栗子
1 3 5 2 4
首先输入1,那么在树状数组角标1的位置加入1,3,5同理
这样在加入3的时候,求出前面有一个和它非逆序
5的时候发现前面有两个数和它非逆序
2的时候发现前面有一个数和它非逆序
4的时候发现前面有三个和它非逆序
那么答案就是从5个数中选两个的组合数-非逆序对数
就是10-7=3

树状数组的一些操作:

l o w b i t lowbit lowbit操作

ll lowbit(ll x){
return x&(-x);}

更新操作

void update(ll i, ll x)//更新操作 {
for (ll pos = i; pos < MAXN; pos += lowbit(pos)) tree[pos] += x;}

求前n项和操作

ll query(ll n)//求前n项和 {
ll ans = 0; for (ll pos = n; pos; pos -= lowbit(pos)) ans += tree[pos]; return ans;}

求区间和操作

ll query(ll a, ll b)//查询 {
return query(b) - query(a - 1);}

本题有一些问题就是:

1.为什么会RE,刚开始做的时候,内心看到满屏的RE是崩溃的。
因为内容的数字可能会大于1e9但是正常的数组没有办法开到如此大,因此需要离散化
2.在离散化过程中如果遇到两数相等会不会出问题
那么就需要在离散化过程中的cmp函数的作用了,如果数值相等,那么这个就不能说是逆序对了,所以需要id小的放到前面去,id大的放到后面去(离散化记录的是相对的位置大小),这样处理的话相等的数值就不会出现误判逆序的问题了。

#include
#include
using namespace std;typedef long long ll;const ll MAXN=6e5;ll tree[MAXN];struct node{
ll id; ll t;}s[2100021];ll a[2102010];ll lowbit(ll x){
return x&(-x);} void update(ll i, ll x)//更新操作 {
for (ll pos = i; pos < MAXN; pos += lowbit(pos)) tree[pos] += x;}ll query(ll n)//求前n项和 {
ll ans = 0; for (ll pos = n; pos; pos -= lowbit(pos)) ans += tree[pos]; return ans;}ll query(ll a, ll b)//查询 {
return query(b) - query(a - 1);}ll cmp(node x,node y){
if(x.t==y.t)return x.id

还是挺考察对树状数组的理解的,好题啊!

转载地址:http://zsjrz.baihongyu.com/

你可能感兴趣的文章