问2个问题,谢谢
  • 板块学术版
  • 楼主gmx0424
  • 当前回复5
  • 已保存回复5
  • 发布时间2023/11/2 18:55
  • 上次更新2023/11/2 20:39:25
查看原帖
问2个问题,谢谢
890233
gmx0424楼主2023/11/2 18:55

https://www.luogu.com.cn/problem/P1908 1,这个思路对嘛 2,61行为什么是id+1---n?没想明白 求大佬回复

/*
题目:求逆序对
思路;
	权值线段树 维护区间内数出现的次数 
	
	先离散化,在离散化b数组中找到原数组a中元素,离散后的下标
	对这个下表进行单点修改
	
	对i这个数的逆序对个数就是,区间[i+1,n]内数出现的次数
	因为, 区间[i+1,n]数加入的比i早,并且比i要大 
	
*/

#include<bits/stdc++.h> 
using namespace std;
const int maxn = 5e5+5;
int n, a[maxn],b[maxn];
int sum[maxn<<2];

void pushup(int rt){
	sum[rt] = sum[rt<<1]+sum[rt<<1|1];
}

void update(int rt, int l, int r, int x){
	if (l == r){
		sum[rt]++;
		return ;
	}
	int mid = (l+r)>>1;
	if(x<=mid) update(rt<<1,l,mid,x);
	else update(rt<<1|1,mid+1,r,x);
	pushup(rt);
}

long long query(int rt, int l, int r, int ql, int qr){
	if (ql <= l && r <= qr){
		return sum[rt];
	}
	long long cnt = 0;
	int mid = (l+r)>>1;
	if(ql<=mid) cnt+=query(rt<<1,l,mid,ql,qr);
	if(qr>mid) cnt+=query(rt<<1|1,mid+1,r,ql,qr);
	return cnt;
}

int main () {
	cin >> n;
	for (int i = 1; i <= n; i++){
		cin >> a[i];
		b[i] = a[i];
	}	
	sort(b+1,b+1+n);
	long long ans = 0;
	for (int i = 1; i<=n; i++){
		int id = lower_bound(b+1,b+1+n,a[i])-b;
		update(1,1,n,id);
		ans += query(1,1,n,id+1,n); 
	}
	cout << ans;
	return 0;
}
2023/11/2 18:55
加载中...