hdu1394(枚举/树状数组/线段树单点更新&区间求和)
题目链接: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(枚举/树状数组/线段树单点更新&区间求和)的更多相关文章
- 树状数组 && 线段树应用 -- 求逆序数
参考:算法学习(二)——树状数组求逆序数 .线段树或树状数组求逆序数(附例题) 应用树状数组 || 线段树求逆序数是一种很巧妙的技巧,这个技巧的关键在于如何把原来单纯的求区间和操作转换为 求小于等于a ...
- 洛谷P2414 阿狸的打字机 [NOI2011] AC自动机+树状数组/线段树
正解:AC自动机+树状数组/线段树 解题报告: 传送门! 这道题,首先想到暴力思路还是不难的,首先看到y有那么多个,菜鸡如我还不怎么会可持久化之类的,那就直接排个序什么的然后按顺序做就好,这样听说有7 ...
- hdu 5147 Sequence II【树状数组/线段树】
Sequence IITime Limit: 5000/2500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem ...
- HDU 3303 Harmony Forever 前缀和+树状数组||线段树
Problem Description We believe that every inhabitant of this universe eventually will find a way to ...
- hdu 1166:敌兵布阵(树状数组 / 线段树,入门练习题)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- 「CodePlus 2017 11 月赛」Yazid 的新生舞会(树状数组/线段树)
学习了新姿势..(一直看不懂大爷的代码卡了好久T T 首先数字范围那么小可以考虑枚举众数来计算答案,设当前枚举到$x$,$s_i$为前$i$个数中$x$的出现次数,则满足$2*s_r-r > 2 ...
- 树状数组 && 线段树
树状数组 支持单点修改 #include <cstdio> using namespace std; int n, m; ], c[]; int lowbit(int x) { retur ...
- hdu1166 敌兵布阵 树状数组/线段树
数列的单点修改.区间求和 树状数组或线段树入门题 #include<stdio.h> #include<string.h> ],N; void add(int x,int a) ...
- hdu 1166 敌兵布阵——(区间和)树状数组/线段树
pid=1166">here:http://acm.hdu.edu.cn/showproblem.php?pid=1166 Input 第一行一个整数T.表示有T组数据. 每组数据第一 ...
随机推荐
- [持续集成]Jenkins 自动化部署 Maven 工程
一.Jenkins 持续部署原理图 基础服务: 1 SVN 服务 SVN是Subversion的简称,是一个开放源代码的版本控制系统.说得简单一点SVN就是用于多个人共同开发同一个项目,共用资源的目的 ...
- 销售订单增强字段 bapi更新
如果增强字段在销售订单抬头(vbak)上,则要将增强字段一并append到如下四个表/结构中: VBAKKOZ VBAKKOZX BAPE_VBAK BAPE_VBAKX 在行项目(vbap)上: V ...
- 微信公众号验证TOKEN
服务端验证微信token header('Content-type:text'); define("TOKEN", "weixin"); $signature ...
- js中的window.open返回object的错误
系统中用javascript中的window.open后,页面返回了一个[object].因为系统的原因,必需使用href="javascript:window.open()"这样 ...
- C++之封装
希望暴露public 希望隐藏private 对象实例化有两种方式,从栈实例化,从堆(new出来的)实例化. 以谁做什么作为核心. public 放前面,private放后面(属性可以定义为priva ...
- 分享知识-快乐自己:SpringMVC 结合使用拦截器(判断是否用户是否已登陆)
基础拦截器操作: 拦截器是一种AOP操作实现,那么在AOP之中用户一定不需要去关注拦截器的存在,用户只需要按照自己已经习惯的处理方式进行代码的编写即可. 首先我们先创建一个自定义的拦截器: packa ...
- Oracle学习笔记_05_ 一个创建表空间、创建用户、授权的完整过程
一.完整命令 su - oracle sqlplus /nolog conn /as sysdba create tablespace scaninvoice logging datafile '/u ...
- Block Change Tracking (块改变跟踪)
理论背景:Block ChangeTracking 是Oracle 10g里推出的特性. Block change tracking 会记录data file里每个block的update 信息,这些 ...
- [转]从onload和DOMContentLoaded谈起
这篇文章是对这一两年内几篇dom ready文章的汇总(文章的最后会标注参考文章),因为浏览器进化的关系,可能他们现在的行为与本文所谈到的一些行为不相符.我也并没有一一去验证,所以本文仅供参考,在具体 ...
- 洛谷 P3804 [模板] 后缀自动机
题目:https://www.luogu.org/problemnew/show/P3804 模仿了一篇题解,感觉很好写啊. 代码如下: #include<cstdio> #include ...