zoukankan      html  css  js  c++  java
  • nyoj 117 找到的倒数 【树阵】+【分离】

    这个问题的解决方案是真的很不错!!!


    思路:建立一个结构体包括val和id。 val就是输入的数,id表示输入的顺序。然后依照val从小到大排序。假设val相等。那么就依照id排序。

    假设没有逆序的话,肯定id是跟i(表示拍好后的顺序)一直一样的。假设有逆序数。那么有的i和id是不一样的。

    所以,利用树状数组的特性。我们能够简单的算出逆序数的个数。

    假设还是不明确的话举个样例。(输入4个数)

    输入:9 -1 18 5

    输出 3.

    输入之后相应的结构体就会变成这样

    val:9 -1 18 5

    id:  1  2  3  4

    排好序之后就变成了

    val :  -1 5 9 18

    id:      2 4  1  3

    之后再利用树状数组的特性就能够解决这个问题了。


    注意:id 要从1開始。

    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define M 1000005
    using std::sort;
    struct node{
    	int id, val;
    }s[M];
    int c[M], n;
    int cmp(node a, node b){
    	if(a.val != b.val) return a.val < b.val;
    	return a.id<b.id;
    }
    
    int lowbit(int x){
    	return x&(-x);
    }
    
    int getsum(int x){
    	int sum = 0;
    	while(x){
    		sum += c[x];
    		x -= lowbit(x);
    	}
    	return sum;
    }
    
    void add(int x){
    	while(x <= M){
    		c[x]++;
    		x += lowbit(x);
    	}
    } 
    int main(){
    	int t, i;
    	scanf("%d", &t);
    	while(t --){
    		scanf("%d", &n);
    		for(i = 1; i<= n; i ++){
    			scanf("%d", &s[i].val);
    			s[i].id = i;
    			//c[i] = 0;
    		}
    		memset(c, 0, sizeof(int)*(n+1));
    		sort(s+1, s+n+1, cmp);
    		long long ans = 0;
    		for( i = 1; i <= n; i ++){
    			add(s[i].id);  //和以下的不能互换
    			ans += (i-getsum(s[i].id));  //这里是(i-getsum(s[i].id))
    		}
    		printf("%lld
    ", ans);
    	}
    	return 0;
    }        
    

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=117

    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    (DP)codeforces
    (树状数组)POJ
    (树状数组)POJ
    (二维树状数组)POJ
    (模拟)HDU
    (暴力+深搜)POJ
    (判连通+暴力)UVA
    (深搜)UVA
    (暴力+各种算法)hihoCoder
    (尺取法)HDU
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4710762.html
Copyright © 2011-2022 走看看