ccnu-线段树-单点更新3-C

来源:互联网 发布:jira连接mysql 编辑:程序博客网 时间:2024/05/21 18:26
C - 单点更新3Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64uSubmit StatusDescriptionThe inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that satisfy i < j and ai > aj. For a given sequence of numbers a1, a2, ..., an, if we move the first m >= 0 numbers to the end of the seqence, we will obtain another sequence. There are totally n such sequences as the following: a1, a2, ..., an-1, an (where m = 0 - the initial seqence) a2, a3, ..., an, a1 (where m = 1) a3, a4, ..., an, a1, a2 (where m = 2) ... an, a1, a2, ..., an-1 (where m = n-1) You are asked to write a program to find the minimum inversion number out of the above sequences.  InputThe input consists of a number of test cases. Each case consists of two lines: the first line contains a positive integer n (n <= 5000); the next line contains a permutation of the n integers from 0 to n-1.  OutputFor each case, output the minimum inversion number on a single line.  Sample Input 101 3 6 9 0 8 5 7 4 2  Sample Output 16 
代码如下:
【还是模板题,~T^T呜呜呜~没把题意读清楚,搞得理解了半天,讨厌死了~话说用线段树比暴力快了100倍呢⊙﹏⊙】
#include <cstdio>#include <algorithm>using namespace std; #define lson l , m , rt << 1#define rson m + 1 , r , rt << 1 | 1const int maxn = 5010;int sum[maxn<<2];void PushUP(int rt) {sum[rt] = sum[rt<<1] + sum[rt<<1|1];}void build(int l,int r,int rt) {sum[rt] = 0;if (l == r) return ;int m = (l + r) >> 1;build(lson);build(rson);}void update(int p,int l,int r,int rt) {if (l == r) {sum[rt] ++;return ;}int m = (l + r) >> 1;if (p <= m) update(p , lson);else update(p , rson);PushUP(rt);}int query(int L,int R,int l,int r,int rt) {if (L <= l && r <= R) {return sum[rt];}int m = (l + r) >> 1;int ret = 0;if (L <= m) ret += query(L , R , lson);if (R > m) ret += query(L , R , rson);return ret;}int x[maxn];int main() {int n;while (~scanf("%d",&n)) {build(0 , n - 1 , 1);int sum = 0;for (int i = 0 ; i < n ; i ++) {scanf("%d",&x[i]);sum += query(x[i] , n - 1 , 0 , n - 1 , 1);update(x[i] , 0 , n - 1 , 1);}int ret = sum;for (int i = 0 ; i < n ; i ++) {sum += n - x[i] - x[i] - 1;ret = min(ret , sum);}printf("%d\n",ret);}return 0;}


	
				
		
原创粉丝点击