树状数组(LA4329,UVaLive4329,Ping pong)

通过这题,对树状数组稍微有了一点模糊的认识,不过还是不太懂。。。(这题做的真的心累。。。最后参考别人的代码才A了的)

#include
using namespace std;
const int maxn = 20000 + 5;
const int maxg = 100000 + 5;
 
int a[maxn];
int c[maxn];//i左边 比i等级低的个数
int d[maxn];//i右边 比i顶级低的个数
int C[maxg];//辅助数组 
int n; 

//void print_x() {  //打印x 
//	cout << "x[i] = ";
//	for(int i = 1; i <= n; i++) {
//		  cout << x[i] << " ";
//	}
//	cout << endl;
//}
//
//void print_C() { //打印C
//	cout << "C[i] = ";
//	for(int i = 1; i <= n; i++) {
//		cout << C[i] << " ";
//	} 
//	cout << endl;
//} 

int lowbit(int i) {
	return i&(-i);
}

int sum(int i) {
	int ret = 0;
	while(i > 0) {
		ret += C[i];
		i -= lowbit(i);
	}
	return ret;
}

void add(int i,int d) {
	while(i <= maxg-1){   //对于等级  而不是对于选手 
		C[i] += d;
		i += lowbit(i);
	}
}

int main() {
	int T;
	cin >> T;
	while(T--) {
		cin >> n;
		for(int i = 1; i <= n; i++) {
			cin >> a[i];
		}
		memset(C, 0, sizeof(C));
		for(int i = 1; i <= n; i++) {//从左往右扫描 
			c[i] = sum(a[i]-1);  //i左边等级比i等级低的总和
			add(a[i], 1);   //将存在的等级  加入辅助数组C中 
		}
		memset(C, 0, sizeof(C)); 
		for(int i = n; i >= 1; i--) { 
			d[i] = sum(a[i]-1); 
			add(a[i], 1); 
		}
		long long ans = 0;
		for(int i = 2; i <= n-1; i++) 
			ans += c[i]*(n-i-d[i]) + (i-1-c[i])*d[i]; 
		cout << ans << endl;
	}
	return 0;
} 


你可能感兴趣的:(数据结构和算法)