hdu1394 Minimum Inversion Number 单点更新

2024-06-12 11:58

本文主要是介绍hdu1394 Minimum Inversion Number 单点更新,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


本题虽归于线段树,但实际上只是求逆序数时使用线段树,后面求最小逆序数时并不需要线段树。
首先题目有两个要点:
1.求出原序列的逆序数
2.求出n次移动第一个位置数到最后的逆序数。


对于第一个要点,实际上用暴力也可以解决,当然最好转到线段树的概念上来。

以下我就引用一下别人的话好了。

/ *

先以区间[0,9]为根节点建立val都为0的线段树,  
再看看怎样求下面序列的逆序数: 
1 3 6 9 0 8 5 7 4 2 
在线段树中插入1, 插入之前先询问区间[1,9]已插入的节点数(如果存在,必与1构成逆序)  v1=0 
在线段树中插入3, 插入之前先询问区间[3,9]已插入的节点数(如果存在,必与3构成逆序)  v2=0 
在线段树中插入6, 插入之前先询问区间[6,9]已插入的节点数(如果存在,必与6构成逆序)  v3=0 
在线段树中插入9, 插入之前先询问区间[9,9]已插入的节点数(如果存在,必与9构成逆序)  v4=0 
在线段树中插入0, 插入之前先询问区间[0,9]已插入的节点数(如果存在,必与0构成逆序)  v5=4 
在线段树中插入8, 插入之前先询问区间[8,9]已插入的节点数(如果存在,必与8构成逆序)  v6=1 
在线段树中插入5, 插入之前先询问区间[5,9]已插入的节点数(如果存在,必与5构成逆序)  v7=3 
在线段树中插入7, 插入之前先询问区间[7,9]已插入的节点数(如果存在,必与7构成逆序)  v8=2 
在线段树中插入4, 插入之前先询问区间[4,9]已插入的节点数(如果存在,必与4构成逆序)  v9=5 
在线段树中插入2, 插入之前先询问区间[2,9]已插入的节点数(如果存在,必与2构成逆序)  v10=7 

累加v1+……+v10  =22,这就是1 3 6 9 0 8 5 7 4 2的逆序数了.

*/ 

第二点:
由于数字0~n-1都是连续的,那么我每次把第一个数字移到最后。
例如,我第一个位置的数字是3,那么移动后。
原本不是逆序数对就变成了逆序数对;
原本是逆序数对的就变成了非逆序数对。


所增加的逆序数对 = n-3-1;
所减少的逆序数对 = 3;

这样基本就不难理解了~

以下放出AC代码:

#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <iostream>
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define min(a,b) a<b?a:b
using namespace std;
const int p = 5005;
int sum [ p<<2 ],cot,a[p];
void build (int l ,int r ,int rt)
{sum[rt]=0;if(l==r)return;int mid = (l + r) >> 1;build(lson);build (rson);
}void query(int l ,int r ,int rt, int x,int y)
{if(x<=l&&r<=y){cot+=sum[rt];return;}int mid = (l + r) >> 1;if(x<=mid)  query(lson,x,y);if(y>mid)  query(rson,x,y);
}void update(int l ,int r ,int rt,int num)
{if(l == r){sum[rt]=1;return;}int mid = (l + r)>>1;if(num<=mid) update(lson,num);if(num>mid) update(rson,num);sum[ rt ]=sum[ rt<<1 ]+sum[ rt<<1|1 ];
}
int main()
{int N,temp;while(scanf("%d",&N)!=EOF){build(0,N-1,1);cot=0;for(int i=1;i<=N;i++){scanf("%d",&a[i]);query(0,N-1,1,a[i],N-1);update(0,N-1,1,a[i]);}int minn=cot;for(int i=1;i<=N;i++){cot = cot - a[i] + N - a[i] - 1 ;minn = min(minn,cot);}printf("%d\n",minn);}return 0;
}



这篇关于hdu1394 Minimum Inversion Number 单点更新的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1054150

相关文章

个人博客文章目录索引(持续更新中...)

文章目录 一、Java基础二、Java相关三、MySql基础四、Mybatis基础及源码五、MybatisPlus基础六、Spring基础及源码七、Tomcat源码八、SpringMVC基础及源码   随着文章数量多起来,每次着急翻找半天,而是新申请的域名下来了,决定整理下最近几年的文章目录索引。(红色标记为常检索文章) 一、Java基础 1、Java基础(一):语言概述2、J

手把手带你实现Android增量更新

Android增量更新技术在很多公司都在使用,网上也有一些相关的文章,但大家可能未必完全理解实现的方式,本篇博客,我将一步步的带大家实现增量更新。 为什么需要增量更新? 当我们开发完一个项目之后,上线维护 , 增加新功能 , 添加第三方库 , APK大小从4 - 5M , 增长到10+M , 用户由原来的几十秒下载 , 到现在几分钟以上的下载 , 网络情况不好的时候 , 或许就是十分钟不等。每

华为欧拉 openEuler24.03 更新 阿里 yum源

华为欧拉 openEuler24.03 更新 阿里 yum源 备份 yum 源编写 阿里云 yum源 配置文件更新 yum 缓存 备份 yum 源 mv /etc/yum.repos.d/openEuler.repo /etc/yum.repos.d/openEuler.repo.bak 编写 阿里云 yum源 配置文件 vim /etc/yum.repos.d/openEuler.r

git 放弃本地修改 强制更新

git fetch --all git reset --hard origin/分支名称 git fetch 只是下载远程的库的内容,不做任何的合并 git reset 把HEAD指向刚刚下载的最新的版本

【从0实现React18】 (四) 如何触发更新 带你了解react触发更新的流程以及更新后如何触发render

常见的触发更新的方式 创建 React 应用的根对象 ReactDOM.creatRoot().render();类组件 this.setState();函数组件 useState useEffect; 我们希望实现一套统一的更新机制,他的特点是: 兼容上述触发更新的方式方便后续拓展(优先级机制) 更新机制的组成部分 代表更新的数据结构 Update消费update的数据结构——Up

Leetcode 3195. Find the Minimum Area to Cover All Ones I

Leetcode 3195. Find the Minimum Area to Cover All Ones I 1. 解题思路2. 代码实现 题目链接:3195. Find the Minimum Area to Cover All Ones I 1. 解题思路 这一题还是挺简单的,只要找到所有1所在的元素的上下左右4个边界,作为目标矩形的四个边即可。 2. 代码实现 给出python

Pwn刷题记录(不停更新)

1、CTFshow-pwn04(基础canary) ​ 好久没碰过pwn了,今天临时做一道吧,毕竟刚联合了WSL和VSCode,想着试着做一道题看看,结果随手一点,就是一个很少接触的,拿来刷刷: ​ 先查看下保护: root@MSI:/home/g01den/Temp# checksec pwn[*] '/home/g01den/Temp/pwn'Arch: i386-32-lit

AtCoder Beginner Contest 359 A~C(D~F更新中...)

A.Count Takahashi 题意 给出 N N N个字符串,每个字符串为以下两种字符串之一: "Takahashi" "Aoki" 请你统计"Takahashi"出现了多少次。 分析 输入并统计即可。 代码 #include <bits/stdc++.h>using namespace std;typedef long long ll;void solve() {i

Linux基本命令有哪些(持续更新中)

Linux基本的命令有mkdir  xxx,此命令用来创建一个目录如:mkdir Linuxstuff(此命令是创建文件Linuxstuff)                                 cd  xxx,此命令用来进入一个指定的目录:cd Linuxstuff(此命令进入Linuxstuff里面去 ls命令是linux下最常用的命令之一,ls跟dos下的dir命令是一样

Linux学习笔记-目录解释、添加删除用户、更新密码

vim hello.c  --编写c程序 gcc hello.c  --编译c程序 ./a.out      --运行c程序 root 存放root用户的相关文件 是一级目录 home 存放普通用户的相关文件 是二级目录 bin 存放常用命令的目录 sbin 存放的是要有一定的权限才可以使用的命令 mnt 默认挂载光驱和软驱的目录 boot 存放引导相关的文件的目录 etc 存放配置相关的