HDU 1394 逆序数 线段树单点跟新 | 暴力
Minimum Inversion Number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 19575 Accepted Submission(s): 11756
For a given sequence of numbers a1, a2, ..., an, if we move the first m >= 0 numbers to the end of the seqence, we will obtain another sequence. There are totally n such sequences as the following:
a1, a2, ..., an-1, an (where m = 0 - the initial seqence)
a2, a3, ..., an, a1 (where m = 1)
a3, a4, ..., an, a1, a2 (where m = 2)
...
an, a1, a2, ..., an-1 (where m = n-1)
You are asked to write a program to find the minimum inversion number out of the above sequences.
10
1 3 6 9 0 8 5 7 4 2
16
求每次将第一个数字放置到最后的逆序数,一共有n个逆序数,从这里面选取最小的一个。
思路:
1.暴力
将初始序列的逆序数求出来,之后的逆序数可以推导出来,假设得到了第一个逆序数 num。此时要将第一个数字data[i]放置到最后一个,那么num就要减去该数的值,重新产生了多少个逆序对呢?产生了n-data[i]-1个。就是序列中比data[i]大的数的个数。这个很容易推导出来。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
using namespace std;
const int maxn=50005;
int ans[maxn];
int main() {
int n;
while(~scanf("%d",&n)) {
for(int i=0;i<n;++i) {
scanf("%d",&ans[i]);
}
int sum=0;
for(int i=0;i<n-1;++i) {
for(int j=i+1;j<=n-1;++j) {
if(ans[i]>ans[j]) sum++;
}
}
int result=sum;
for(int i=0;i<n-1;++i) {
sum=sum-ans[i]+(n-ans[i]-1);
result=min(result,sum);
}
printf("%d\n",result);
}
return 0;
}
2.用线段树来做。
有了上面的推导,只要求出第一个,剩余的工作就变的简单了。
再用线段树求原始序列的时候要反向思维,求每一个数之前的序列中比自身大的个数。
假设现在给出一个序列是 : 4 3 1 5 0 2
我们在一边度数据的过程中计算逆序对的个数。初始话每个线段树的结点值都赋值为0。
先读到5,查询4-(n-1)区间即4-4有没有出现比4大的,没有,返回0。查询完成之后将该节点插入线段树。
再读到3,查询3-(n-1)区间有没有比3大的,返回1,将3插入。再将3插入线段树。以此类推...这样我们得到如下结果:
4 : 0
3 : 1(4)
1 : 2(3,4)
5 : 0
0 : 4(1,3,4,5)
2 : 3(3,4,5)
该序列的逆序数就是0+1+2+0+4+3=10。与我们求一般求逆序数时得到的结果相同。
注意是0-n-1的序列,建树注意下标
代码:
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
const int maxn=5005;
int sum[maxn<<2];
int data[maxn];
void pushup(int rt) {
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void build(int l, int r, int rt) {
sum[rt]=0;
if(l==r)return;
int mid=(l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}
void update(int val, int l, int r, int rt) {
if(l==r) {
sum[rt]++;return;
}
int mid=(l+r)>>1;
if(val<=mid) update(val,lson);
else update(val,rson);
pushup(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)>>1,cnt=0;
if(L<=mid) cnt+=query(L,R,lson);
if(R>mid) cnt+=query(L,R,rson);
return cnt;
}
int main() {
int n;
while(~scanf("%d",&n)) {
int result,temp=0;
build(0,n-1,1);
for(int i=0;i<n;++i) {
scanf("%d",&data[i]);
temp+=query(data[i],n-1,0,n-1,1);
update(data[i],0,n-1,1);
}
result=temp;
for(int i=0;i<n;++i) {
temp=temp-data[i]+(n-1-data[i]);
result=min(result,temp);
}
printf("%d\n",result);
}
return 0;
}
HDU 1394 逆序数 线段树单点跟新 | 暴力的更多相关文章
- HDU 1394 Minimum Inversion Number(最小逆序数 线段树)
Minimum Inversion Number [题目链接]Minimum Inversion Number [题目类型]最小逆序数 线段树 &题意: 求一个数列经过n次变换得到的数列其中的 ...
- HDU 1754 线段树 单点跟新 HDU 1166 敌兵布阵 线段树 区间求和
I Hate It Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- hdu 1394 逆序数(线段树)
http://acm.hust.edu.cn/vjudge/problem/15764 http://blog.csdn.net/libin56842/article/details/8531117 ...
- HDU 1394 (逆序数) Minimum Inversion Number
原来求逆序数还可以用线段树,涨姿势了. 首先求出原始序列的逆序数,然后递推每一个序列的逆序数. #include <cstdio> #include <cstring> #in ...
- hdu 1540 Tunnel Warfare 线段树 单点更新,查询区间长度,区间合并
Tunnel Warfare Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pi ...
- hdu 1541 Stars(线段树单点更新,区间查询)
题意:求坐标0到x间的点的个数 思路:线段树,主要是转化,根据题意的输入顺序,保证了等级的升序,可以直接求出和即当前等级的点的个数,然后在把这个点加入即可. 注意:线段树下标从1开始,所以把所有的x加 ...
- 51Nod 1019 逆序数(线段树)
题目链接:逆序数 模板题. #include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a) ...
- hdu 2795 Billboard(线段树单点更新)
Billboard Time Limit: 20000/8000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- POJ 2299 Ultra-QuickSort 求逆序数 线段树或树状数组 离散化
我用的线段树写的. num数组表示已插入的数值的个数. 由于a[i]数值很大,但是n不是很大,所以要离散化处理 9 1 0 5 4 离散化后 4 1 0 3 2 这样保证最大值不会超过n #inclu ...
随机推荐
- LeetCode 543. Diameter of Binary Tree (二叉树的直径)
Given a binary tree, you need to compute the length of the diameter of the tree. The diameter of a b ...
- Mysql 用户,权限管理的几点理解。
前两天项目数据库要移植到mysql,为此临时抓了几天很久没用的mysql. 公司的数据库比较简单,从oracle迁移到mysql很简单,但是,中间的权限管理让我感觉既简单又复杂..简单是因为网上关于m ...
- 从零起步学python计划及感想
从纯传统bi转型过来的技术顾问,比较有优势的是对业务的熟悉,对数据有敏感度,熟悉数据模型.但是长年累月基本都是用sql处理问题.目前还没有经历过sql解决不了的问题,一个sql解决不了就用临时表,几个 ...
- C语言编写一个简单游戏
感悟:这算是一个起点吧,我都大二了,还这么菜,才开始写游戏,这个游戏很简单,利用随机数猜大小! #include <stdlib.h> #include <stdio.h> # ...
- Ionic3 创建应用后,目录结构
ionic start myApp blank (空项目) hooks --编译cordova时自定义的脚本命令,方便整合到我们的编译系统和版本控制系统中 node_modules --node各类依 ...
- 【机器学习实战】第12章 使用FP-growth算法来高效发现频繁项集
第12章 使用FP-growth算法来高效发现频繁项集 前言 在 第11章 时我们已经介绍了用 Apriori 算法发现 频繁项集 与 关联规则.本章将继续关注发现 频繁项集 这一任务,并使用 FP- ...
- AngularJS学习篇(七)
AngularJS 过滤器 过滤器可以使用一个管道字符(|)添加到表达式和指令中. <!DOCTYPE html> <html> <head> <meta c ...
- ASP.NET Core中的OWASP Top 10 十大风险-失效的访问控制与Session管理
不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻喷,如觉得我翻译有问题请挪步原博客地址 本博文翻译自: https://dotnetcoretutorials.com/201 ...
- PHP静态化技术
很多框架的模板引擎都有页面静态化的功能 目的是为了优化网站运行时间 静态化分两种 纯静态和伪静态 一. 纯静态 纯静态展示的是实实在在的静态页面 运行PHP程序 判断是否存在静态页 如果存在 展示 ...
- js 根据身份证号获取性别,年龄,等
$(function(){ $("#corpOwnerIdno").blur(function(){ //获取输入身份证号码 ...