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

题意:给出一个循环数组,求其逆序对最少为多少;

思路:对于逆序对: 交换两个相邻数,逆序数 +1 或 -1, 交换两个不相邻数 a, b, 逆序数 += 两者间大于 a 的个数 - 两者间小于 a 的个数;

所以只要求出初始时的逆序对数,就可以推出其余情况时的逆序对数.对于求初始逆序对数,这里 n 只有 5e3,可以直接暴力 / 树状数组 / 线段树 / 归并排序;

代码:

1.直接暴力

 #include <iostream>
#include <stdio.h>
using namespace std; const int MAXN = 5e3 + ;
int a[MAXN]; int main(void){
int n, ans = ;
while(~scanf("%d", &n)){
ans = ;
for(int i = ; i < n; i++){
scanf("%d", &a[i]);
for(int j = ; j < i; j++){
if(a[j] > a[i]) ans++;
}
}
int cnt = ans;
for(int i = ; i < n; i++){
cnt += (n - a[i] - ) - a[i];
ans = min(ans, cnt);
}
printf("%d\n", ans);
}
return ;
}

2.树状数组

 #include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std; const int MAXN = 5e3 + ;
int tree[MAXN], a[MAXN], n; int lowbit(int x){
return x & (-x);
} void updata(int x, int d){
while(x <= n){
tree[x] += d;
x += lowbit(x);
}
} int sum(int x){
int ans = ;
while(x > ){
ans += tree[x];
x -= lowbit(x);
}
return ans;
} int main(void){
int ans = ;
while(~scanf("%d", &n)){
ans = ;
memset(tree, , sizeof(tree));
for(int i = ; i <= n; i++){
scanf("%d", &a[i]);
updata(a[i] + , );
ans += i - sum(a[i] + );//当前是第 i 个数,减去a[i]前面(这里包括了a[i])的数就是a[i]后面的数了,即可以和a[i]组成逆序对的数的数目
// ans += sum(n) - sum(a[i] + 1);
}
int cnt = ans;
for(int i = ; i <= n; i++){
cnt += (n - a[i] - ) - a[i];
ans = min(ans, cnt);
}
printf("%d\n", ans);
}
return ;
}

3.线段树

 #include <iostream>
#include <stdio.h>
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
using namespace std; const int MAXN = 5e3 + ;
int sum[MAXN << ], a[MAXN]; void push_up(int rt){
sum[rt] = sum[rt << ] + sum[rt << | ];
} void build(int l, int r, int rt){
sum[rt] = ;
if(l == r) return;
int mid = (l + r) >> ;
build(lson);
build(rson);
} void update(int p, int x, int l, int r, int rt){
if(l == r){
sum[rt] += x;
return;
}
int mid = (l + r) >> ;
if(p <= mid) update(p, x, lson);
else update(p, x, rson);
push_up(rt);
} int query(int L, int R, int l, int r, int rt){
if(l >= L && r <= R) return sum[rt];
int mid = (l + r) >> ;
int ans = ;
if(L <= mid) ans += query(L, R, lson);
if(R > mid) ans += query(L, R, rson);
return ans;
} int main(void){
int n, ans = ;
while(~scanf("%d", &n)){
ans = ;
build(, n-, );
for(int i = ; i < n; i++){
scanf("%d", &a[i]);
ans += query(a[i], n - , , n - , );
update(a[i], , , n - , );
}
int cnt = ans;
for(int i = ; i < n; i++){
cnt += (n - a[i] - ) - a[i];
ans = min(ans, cnt);
}
printf("%d\n", ans);
}
return ;
}

hdu1394(枚举/树状数组/线段树单点更新&区间求和)的更多相关文章

  1. 树状数组 && 线段树应用 -- 求逆序数

    参考:算法学习(二)——树状数组求逆序数 .线段树或树状数组求逆序数(附例题) 应用树状数组 || 线段树求逆序数是一种很巧妙的技巧,这个技巧的关键在于如何把原来单纯的求区间和操作转换为 求小于等于a ...

  2. 洛谷P2414 阿狸的打字机 [NOI2011] AC自动机+树状数组/线段树

    正解:AC自动机+树状数组/线段树 解题报告: 传送门! 这道题,首先想到暴力思路还是不难的,首先看到y有那么多个,菜鸡如我还不怎么会可持久化之类的,那就直接排个序什么的然后按顺序做就好,这样听说有7 ...

  3. hdu 5147 Sequence II【树状数组/线段树】

    Sequence IITime Limit: 5000/2500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem ...

  4. HDU 3303 Harmony Forever 前缀和+树状数组||线段树

    Problem Description We believe that every inhabitant of this universe eventually will find a way to ...

  5. hdu 1166:敌兵布阵(树状数组 / 线段树,入门练习题)

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  6. 「CodePlus 2017 11 月赛」Yazid 的新生舞会(树状数组/线段树)

    学习了新姿势..(一直看不懂大爷的代码卡了好久T T 首先数字范围那么小可以考虑枚举众数来计算答案,设当前枚举到$x$,$s_i$为前$i$个数中$x$的出现次数,则满足$2*s_r-r > 2 ...

  7. 树状数组 && 线段树

    树状数组 支持单点修改 #include <cstdio> using namespace std; int n, m; ], c[]; int lowbit(int x) { retur ...

  8. hdu1166 敌兵布阵 树状数组/线段树

    数列的单点修改.区间求和 树状数组或线段树入门题 #include<stdio.h> #include<string.h> ],N; void add(int x,int a) ...

  9. hdu 1166 敌兵布阵——(区间和)树状数组/线段树

    pid=1166">here:http://acm.hdu.edu.cn/showproblem.php?pid=1166 Input 第一行一个整数T.表示有T组数据. 每组数据第一 ...

随机推荐

  1. Java中synchronized

    原文地址 synchronized是Java中的关键字,是一种同步锁.它修饰的对象有以下几种:1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用 ...

  2. <密码学入门>关于DES加密算法解密算法相关问题

    题外话:个人觉得DES加密解密真的是一种过程冗长的方法,S盒,P盒还有各种各样的变换让人眼花缭乱. (一)Feistel密码结构 要先说Feistel密码结构的原因是DES加密过程是和Feistel密 ...

  3. TCP/IP协议数据包文件PCAP分析器

    一.设计原理 1.PCAP文件构成 参考http://blog.csdn.net/gulu_gulu_jp/article/details/50494909 PCAP文件由一个PCAP文件头和多个PC ...

  4. BZOJ 1201 [HNOI2005]数三角形:枚举 + 前缀和

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1201 题意: 有一个边长为n的正三角形网格,去掉其中一些线段,问你在这幅图中有多少个三角形 ...

  5. blog集合

    godiscoder的技术blog 一个不错的技术架构设计blog MySQLOPS 数据库与运维自动化技术分享 stone的技术blog 陈皓专栏 风雪涟漪的技术blog 华为首席科学家 张宴技术b ...

  6. hdu 6109 数据分割

    /** * 题目描述有点坑,勉强能读懂,大致意思,有多组约束条件.原本每组数据之间是有分界符号的 * 现在分界符号没了,让你找出原来每组数据多少个条件,并且告诉,每组的最后一个条件会使得与前面的 * ...

  7. hdu-5813 Elegant Construction(贪心)

    题目链接: Elegant Construction Time Limit: 4000/2000 MS (Java/Others)     Memory Limit: 65536/65536 K (J ...

  8. PS 滤镜— —球面化效果

    clc; clear all; close all; addpath('E:\PhotoShop Algortihm\Image Processing\PS Algorithm'); I=imread ...

  9. linux增加vlan网卡配置

    1.编辑文件/etc/sysconfig/network在里面添加一行:VLAN=yes2.再生成网卡设备的配置文件ifcfg-eth1.10和ifcfg-eth1.240cd /etc/syscon ...

  10. scala新人佑门

    scala语言 1. val和var val和var当前区别在于前者只能被赋值一次,就像java中的final,但是后者则可以随意覆盖: 2. Unit Unit返回代表空返回,类似于vo 3. 类型 ...