http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4046

题意:有一个含有n个元素的数列p,每个元素均不同且为1~n中的一个,求出将数列变为循环递增序列至少需要左右相邻的数交换多少次

题目分析:先看简化版的题目:如果只有1 2 3 4 5是符合要求的,那么交换次数根据冒泡排序可得就是逆序数,直接树状数组求逆序数即可.

由于题目要求只要只要是循环递增数列即可,也就是1 2 3 4 5 和 2 3 4 5 1都是符合要求的.那么就要枚举数字1出现的位置了,如果暴力求解显然会TLE,而可以发现1 2 3 4 5 和2 3 4 5 1所需交换次数的差就是(n - pos[ 1 ] )- (pos[ 1 ] - 1 )(其中pos[ i ]表示数字i的起始位置),因为不管1起始位置在哪,得到1 2 3 4 5的时候都可以先把1移动到第一个位置,然后移动2 3 4 5的相对位置,得到2 3 4 5 1的时候都可以先把1移动到最后一个位置,然后移动2 3 4 5的相对位置,所以移动成1 2 3 4 5与移动成2 3 4 5 1的次数之差就是 (n - pos[ 1 ] )- (pos[ 1 ] - 1 ).正是因为可以分别把数字移动到首位置和末位置,才可以直接根据(n - pos[ i ] )- (pos[ i ] - 1 )计算差值,所以需要分别计算1 2 3 4 5    2 3 4 5 1     3 4 5 1 2       4 5 1 2 3       5 1 2 3 4

 #include <iostream>
#include <iomanip>
#include <algorithm>
#include <map>
# include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5+;
int n, id[maxn], sum[maxn];
void add(int x){
for(;x<=n;x+=x&-x) ++sum[x];
}
int query(int x){
int res = ;
for(;x>;x-=x&-x) res += sum[x];
return res;
} int main(){
int T, x;
for(scanf("%d",&T);T;--T){
scanf("%d",&n);
for(int i=; i<=n; ++i){
scanf("%d",&x);
id[x] = i;
sum[i] = ;
}
LL tot = , ans;
for(int i=n; i>; --i){
tot += query(id[i]);
add(id[i]);
}
ans = tot;
for(int i=; i<=n;++i){
tot += n-id[i];
tot -= id[i]-;
ans = min(ans, tot);
}
printf("%lld\n",ans);
}
return ;
}

[zoj4046][树状数组求逆序(强化版)]的更多相关文章

  1. Ultra-QuickSort(树状数组求逆序对数)

    Ultra-QuickSort 题目链接:http://poj.org/problem?id=2299 Time Limit: 7000MS   Memory Limit: 65536K Total ...

  2. 用树状数组求逆序对数(poj2299)

    Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 46995   Accepted: 17168 ...

  3. 【CDOJ931】Car race game(树状数组求逆序)

    题目连接:http://acm.uestc.edu.cn/#/problem/show/931 OJ评判系统有些坑,不支持__int64以及输出的%I64d大家注意.全开long long也会TLE, ...

  4. POJ-2299 Ultra-QuickSort(用树状数组求逆序对数)

    题目链接 ac代码 #include<iostream> #include<cstdio> #include<cstring> #include<algori ...

  5. poj 2299 Ultra-QuickSort(树状数组求逆序数+离散化)

    题目链接:http://poj.org/problem?id=2299 Description In this problem, you have to analyze a particular so ...

  6. POJ2299Ultra-QuickSort(归并排序 + 树状数组求逆序对)

    树状数组求逆序对   转载http://www.cnblogs.com/shenshuyang/archive/2012/07/14/2591859.html 转载: 树状数组,具体的说是 离散化+树 ...

  7. 【bzoj2789】[Poi2012]Letters 树状数组求逆序对

    题目描述 给出两个长度相同且由大写英文字母组成的字符串A.B,保证A和B中每种字母出现的次数相同. 现在每次可以交换A中相邻两个字符,求最少需要交换多少次可以使得A变成B. 输入 第一行一个正整数n ...

  8. 2021.12.10 P5041 [HAOI2009]求回文串(树状数组求逆序对)

    2021.12.10 P5041 [HAOI2009]求回文串(树状数组求逆序对) https://www.luogu.com.cn/problem/P5041 题意: 给一个字符串 \(S\) ,每 ...

  9. HDU 1394 Minimum Inversion Number ( 树状数组求逆序数 )

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 Minimum Inversion Number                         ...

随机推荐

  1. Win10系列:VC++绘制几何图形5

    打开D2DBasicAnimation.h头文件,并在D2DBasicAnimation类中添加如下的代码: private:     //声明成员变量point     D2D1_POINT_2F ...

  2. TNS

    Oracle中TNS的完整定义:transparence Network Substrate透明网络底层,监听服务是它重要的一部分,不是全部,不要把TNS当作只是监听器 ORACLE当中,如果想访问某 ...

  3. Android 应用基础知识和应用组件

    应用基础知识 安装到设备后,每个 Android 应用都运行在自己的安全沙箱内: Android 操作系统是一种多用户 Linux 系统,其中的每个应用都是一个不同的用户: 默认情况下,系统会为每个应 ...

  4. Java获取系统时间的四种方法

    1.Date day=new Date(); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); ...

  5. Invalid MEX-file: caffe.mexa64 的解决方案

    http://blog.csdn.net/iamzhangzhuping/article/details/53105708

  6. 7.4 C++标准模板库(STL)的概念

    参考:http://www.weixueyuan.net/view/6401.html 总结:  标准模板库为C++提供了完善的数据结构及算法. 标准模板库包括三部分:容器.算法和迭代器. 容器是对象 ...

  7. 7.1 C++模板基本概念及语法 《C++模板与标准模板库》

    参考:http://www.weixueyuan.net/view/6398.html 总结: 模板是另一种代码重用机制. 需要设计的几个类,其功能都是一样的,仅仅只是需要操作的数据类型不同. 有更好 ...

  8. 第一章 使用功能测试协助安装Django

    1.1 第一个简单的测试--断言 from selenium import webdriver browser = webdriver.Firefox() browser.get('http://lo ...

  9. JavaScript示例

    <!DOCTYPE html> <html> <head> <title>单击按钮事件示例</title> <script langu ...

  10. DevExpress ASP.NET Core Controls v18.2新功能详解

    行业领先的.NET界面控件2018年第二次重大更新——DevExpress v18.2日前正式发布,本站将以连载的形式为大家介绍新版本新功能.本文将介绍了DevExpress ASP.NET Core ...