zoukankan      html  css  js  c++  java
  • PAT顶级 1027 Larry and Inversions (35分)(树状数组)

    题目链接:

    1027 Larry and Inversions (35分)

    思路:

    首先计算出原数组逆序数的对数;
    然后依次考虑翻转的情况,我们注意到翻转是有规律的:
    假设我们已经计算得出了从i翻转到j的逆序数对数,则计算i翻转到j+1的逆序数对数,我们只需知道i到j的数中比第j+1个数小的数的个数,我们记为sm,则比j+1个数大的数的数量自然就是j-i-sm,记为gt,那此次翻转我们新获得的逆序数有sm个,损失的逆序数有gt个;
    以上方法需要熟练使用树状数组;

    代码:

    #include<bits/stdc++.h>
    #define lowbit(x) (x&-x)
    
    using namespace std;
    
    const int maxn = 1234;
    int n, a[maxn], sum;
    void init_(){
    	vector<int> bit(n + 1);
    	for(int i = n - 1; i >= 0; i--){
    		int x = a[i], y = a[i];
    		while(x) sum += bit[x], x -= lowbit(x);
    		while(y <= n) ++bit[y], y += lowbit(y);
    	}
    }
    void solve(){
    	for(int i = 0; i < n; i++){
    		int ans = 0;
    		vector<int> bit(n + 1);
    		for(int j = i; j < n; j++){
    			int x = a[j], y = a[j], sm = 0, gt = 0;
    			while(x) sm += bit[x], x -= lowbit(x);
    			while(y <= n) ++bit[y], y += lowbit(y);
    			gt = j - i - sm;
    			ans = ans + sm - gt;
    			if(i || j) putchar(' ');
    			printf("%d", sum + ans);
    		}
    	}
    }
    int main(){
    //	freopen("Sakura.txt", "r", stdin);
    	scanf("%d", &n);
    	for(int i = 0; i < n; i++) scanf("%d", a + i);
    	init_();
    	solve();
    	return 0;
    }
    
  • 相关阅读:
    在阿里云服务器上安装MySQL
    mui中调用ajax时报abort错误
    IDEA根据数据库表生成pojo对象
    java.io.IOException: All specified directories have failed to load.
    mysql隔离级别
    java8新特性
    数据库语言分类
    Spring AOP 代码示例
    java NIO学习(二)
    java NIO学习(一)
  • 原文地址:https://www.cnblogs.com/yuhan-blog/p/12308700.html
Copyright © 2011-2022 走看看