ACM/ICPC 之 数据结构-线段树思想(POJ2182,含O(n^2)插入式解法)
这道题在一定程度上体现了线段树的一种用法,解决的问题是:对于总计n个元素的第i个元素,已知其在[1,i]上部分序列的排名,求第i个元素在所有n个元素中的排名。
当然这道题数据比较水,所以用O(n^2)的直接解法也可以解出,在这里,我也给出自己的O(n^2)解法。
题目大意:
n头乱序的牛排列在一行,每头牛都有一个牌号(1-n),现在知道所有牛此前有多少头牛的牌号比该牛的牌号要小,求每头牛的牌号。
直接解法(插入式):
从前向后遍历每一个数据,每次都进行一次插入。
具体来说:例如对于(1,0,1)这样的序列,我们先设brand[1] = 1。
由第一个数据(1)有brand[2] = 2 ————有排名为:(1,2)
由第二个数据(0)有brand[3] = 1,此时遍历此前所有元素,查询到>=brand[3]则加一个排名,得到brand[1] = 2,brand[2] = 3; ——排名(2,3,1)
由第三个数据(1)有brand[4] = 2,此时遍历此前元素,参照上面的方法,得到brand[1] = 3,brand[2] = 4; ——(3,4,1,2)
那么最后能够得到排名(3,4,1,2);
Code如下:
//普通的O(n^2)算法-直接的想法
//n头牛,已知第i头牛在1-i部分序列的排名,求所有牛的牌号(排名)
//Memory: 236K Time:375Ms
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAX 8005
int n; //cow头量
int small[MAX]; //比第i头cow靠前但牌号较小的cow头量
int brand[MAX]; //牌号
int main()
{
scanf("%d", &n);
brand[] = ;
for (int i = ; i <= n; i++)
{
scanf("%d", &small[i]);
brand[i] = small[i] + ;
if (small[i] + != i) //不是排在最后
{
for (int j = ; j < i; j++)
{
if (brand[j] >= brand[i]) //>=该序号则+1
brand[j]++;
}
}
}
for (int i = ; i <= n; i++)
printf("%d\n", brand[i]);
return ;
}
插入式-解法
线段树解法:
大体想法就是:用线段树存储一个从1-n的顺序排名,将数据从后向前遍历,每次遍历到某一个位置时,假设原数据为s[],那么对于s[i],其在1-i的排名就是s[i]+1,那么在线段树中将[s[i]+1,s[i]+1]区间的sum置为0(减去1)。也就是删去s[i]+1这个排名,这样排名的整体规模就缩小了一个单位,即原为n个元素排名,现在是n-1个元素排名(第s[i]+1排名被删去),并保留原排名数值不变。
这样不断遍历,不断缩减排名的规模就可以依次反向得到该乱序的牛的牌号,然后顺序输出牌号即可
Code如下:
//线段树
//n头牛,已知第i头牛在1-i部分序列的排名,求所有牛的牌号(排名)
//Memory: 432K Time:47Ms
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAX 8005
int n; //cow头量
int small[MAX]; //比第i头cow靠前但牌号较小的cow头量
int brand[MAX]; //牌号
//Brand interval数组
struct Brands{
int l, r; //牌号区间
int sum; //头数
}tree[*MAX];
/*从x开始搭建interval tree*/
void build(int x,int l,int r)
{
tree[x].l = l;
tree[x].r = r;
if (l == r){
tree[x].sum = ;
return;
}
int mid = (l + r) / ;
build( * x, l, mid); //left son
build( * x + , mid + , r); //right son
tree[x].sum = tree[ * x].sum + tree[ * x + ].sum;
}
int query(int x, int v)
{
tree[x].sum--;
// Hit!
if (tree[x].l == tree[x].r)
return tree[x].l;
if (v <= tree[ * x].sum) //<=左结点未删减序列数量
query( * x, v);
else query( * x + , v - tree[ * x].sum);
}
int main()
{
scanf("%d", &n);
for (int i = ; i <= n; i++)
scanf("%d", &small[i]);
small[] = ;
build(, , n);
for (int i = n; i >= ; i--)
brand[i] = query(, small[i] + ); //牌号
for (int i = ; i <= n; i++)
printf("%d\n", brand[i]);
return ;
}
线段树-解法
ACM/ICPC 之 数据结构-线段树思想(POJ2182,含O(n^2)插入式解法)的更多相关文章
- ACM/ICPC 之 数据结构-线段树+区间离散化(POJ2528)
这道题用线段树做更方便更新和查询,但是其数据范围很大,因此要将离散化和线段树结合起来,算是一道比较经典的线段树+离散化的例题. 线段树的离散化有很多方法,在这里,我先用一次结点离散化,间接将源左右端点 ...
- 算法手记 之 数据结构(线段树详解)(POJ 3468)
依然延续第一篇读书笔记,这一篇是基于<ACM/ICPC 算法训练教程>上关于线段树的讲解的总结和修改(这本书在线段树这里Error非常多),但是总体来说这本书关于具体算法的讲解和案例都是不 ...
- Sum of Squares of the Occurrence Counts解题报告(后缀自动机+LinkCutTree+线段树思想)
题目描述 给定字符串\(S(|S|\le10^5)\),对其每个前缀求出如下的统计量: 对该字符串中的所有子串,统计其出现的次数,求其平方和. Sample Input: aaa Sample Out ...
- ACM: Billboard 解题报告-线段树
Billboard Time Limit:8000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Descript ...
- UPC 2224 Boring Counting ★(山东省第四届ACM程序设计竞赛 tag:线段树)
[题意]给定一个长度为N的数列,M个询问区间[L,R]内大于等于A小于等于B的数的个数. [题目链接]http://acm.upc.edu.cn/problem.php?id=2224 省赛的时候脑抽 ...
- CF 787D Legacy(线段树思想构图+最短路)
D. Legacy time limit per test 2 seconds memory limit per test 256 megabytes input standard input out ...
- ACM: Hotel 解题报告 - 线段树-区间合并
Hotel Time Limit:3000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu Description The ...
- sdut 2159 Ivan comes again!(2010年山东省第一届ACM大学生程序设计竞赛) 线段树+离散
先看看上一个题: 题目大意是: 矩阵中有N个被标记的元素,然后针对每一个被标记的元素e(x,y),你要在所有被标记的元素中找到一个元素E(X,Y),使得X>x并且Y>y,如果存在多个满足条 ...
- ACM-ICPC 2017 Asia Xi'an A XOR (线性基+线段树思想)
题目链接 题意;给个数组,每次询问一个区间你可以挑任意个数的数字异或和 然后在或上k的最大值 题解:线性基不知道的先看这个,一个线性基可以log的求最大值把对应去区间的线性基求出来然后用线段树维护线性 ...
随机推荐
- 总结一下安装linux系统经验-版本选择-安装ubuntu
linux版本选择: 初次接触,建议选 Ubuntu 或者 Fedora,这两个发行版都很容易上手,而且两者都有很强大的中文社区,遇到问题比较容易解决,而且都有国内的源,安装或者更新软件时体验相对会好 ...
- c# 多线程 --Mutex(互斥锁)
互斥锁(Mutex) 互斥锁是一个互斥的同步对象,意味着同一时间有且仅有一个线程可以获取它. 互斥锁可适用于一个共享资源每次只能被一个线程访问的情况 函数: //创建一个处于未获取状态的互斥锁 Pub ...
- 导入excel错误:外部表不是预期的格式 解决方案
环境:win7+iis7+Office2007 在asp.net网站中导出Excel文件后,再把文件导入到数据库中. 读取Excel文件时,打开连接出错. 错误为:外部表不是预期的格式 解决:检查了一 ...
- 在c#中运行js脚本(将js文件生成为.dll文件)
原文链接:http://www.cnblogs.com/xhan/archive/2010/10/22/1857992.html 前言: 本来在搞一个Google翻译的接口--向Google翻译发送请 ...
- 电脑开机黑屏,显示Reboot and Select proper boot device!
“reboot and select proper boot device or insert boot media in selected boot device and press a key” ...
- 关于QString::toWCharArray 无法解析的外部符号
1>CommManger.obj : error LNK2019: 无法解析的外部符号 "public: int __thiscall QString::toWCharArray(un ...
- 跨域攻击xss
要完全防止跨域攻击是很难的,对于有些站点是直接 拦截跨域的访问,在你从本站点跳转到其他站点时提醒,这算是一种手段吧. 而跨域攻击的发起就是在代码(包括html,css,js或是后台代码,数据库数据)里 ...
- OC第一节 —— 类和对象
一.类和对象的概念 1.1类 自己的定义: 具有相同或相似性质对象的抽象. 1.2 对象 自己的定义: 对象是人们要进行研究的任何物体,从最简单的整数到复杂的飞机 等均可以看做是对象. 举例说明: 类 ...
- JS的构造函数
//构造函数 //使自己的对象多次复制,同时实例根据设置的访问等级可以访问其内部的属性和方法 //当对象被实例化后,构造函数会立即执行它所包含的任何代码 function myObject(ms ...
- W3Cschool菜鸟教程离线版下载链接
请在电脑上打开以下链接进行下载w3cschool 离线版(chm):http://pan.baidu.com/s/1bniwRCV(最新,2014年10月21日更新)w3cschool 离线版(htm ...