题目链接:1513 - Movie collection

题意:有一堆电影,按1-n顺序排,有m次操作,每次询问第ai个电影之前有多少个电影,然后将其抽出放在堆顶。

分析:线段树应用。

因为每次查询后要将电影移至堆顶,所以我们可以将线段树的区间开到maxn+n,[1,maxn]先置0,在[maxn+1,maxn+n]建树将值置为1,线段树每一段区间的值代表该区间的和。

每次查询后要将该位置的值更新为0,由于要将电影移至堆顶,用一个指针cnt初始化为maxn,记录当前电影可以移到的位置,

由于位置是变化的,所以要用一个数组indice[]来记录每个电影当前所在的位置,每次移动位置只要indice[x]=cnt--即可。

查询的时候只要查询[1,indice[x]-1]区间和就行了。

AC代码如下:

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn=+;
int add[maxn<<];
int tree[maxn<<];
int indice[maxn];
int n,num;
void pushup(int rt)
{
tree[rt]=tree[rt<<]+tree[rt<<|];
}
void update(int p,int x,int l,int r,int rt)
{
if(l==r)
{
tree[rt]=x;
return ;
}
int m=(l+r)>>;
if(p<=m)
update(p,x,lson);
else
update(p,x,rson);
pushup(rt);
}
int query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)
return tree[rt];
int m=(l+r)>>;
int ret=;
if(L<=m)
ret+=query(L,R,lson);
if(R>m)
ret+=query(L,R,rson);
return ret;
}
void build(int l,int r,int rt)
{
if(l==r)
{
num++;
if(num>maxn)
tree[rt]=;
return ;
}
int m=(l+r)>>;
build(lson);
build(rson);
pushup(rt);
}
int main()
{
int t,m,i,x,index;
scanf("%d",&t);
while(t--)
{
memset(tree,,sizeof(tree));
scanf("%d%d",&n,&m);
num=;
build(,maxn+n,);
for(int i=;i<=n;i++)
indice[i]=maxn+i;
int cnt=maxn;
for(i=;i<m;i++)
{
scanf("%d",&x);
printf("%d",query(,indice[x]-,,maxn+n,));
if(i!=m-) printf(" ");
update(indice[x],,,maxn+n,);
indice[x]=cnt--;
update(indice[x],,,maxn+n,);
}
printf("\n");
}
return ;
}

uva 1513(线段树)的更多相关文章

  1. uva 11525(线段树)

    题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  2. UVA 11297 线段树套线段树(二维线段树)

    题目大意: 就是在二维的空间内进行单个的修改,或者进行整块矩形区域的最大最小值查询 二维线段树树,要注意的是第一维上不是叶子形成的第二维线段树和叶子形成的第二维线段树要  不同的处理方式,非叶子形成的 ...

  3. UVa 11992 (线段树 区间修改) Fast Matrix Operations

    比较综合的一道题目. 二维的线段树,支持区间的add和set操作,然后询问子矩阵的sum,min,max 写完这道题也是醉醉哒,代码仓库里还有一份代码就是在query的过程中也pushdown向下传递 ...

  4. UVa 1400 (线段树) "Ray, Pass me the dishes!"

    求一个区间的最大连续子序列,基本想法就是分治,这段子序列可能在区间的左半边,也可能在区间的右半边,也有可能是横跨区间中点,这样就是左子区间的最大后缀加上右子区间的最大前缀之和. 线段树维护三个信息:区 ...

  5. UVA 11992 线段树

    input r c m      r<=20,1<=m<=20000 m行操作 1 x1 y1 x2 y2 v       add v 2 x1 y1 x2 y2 v       s ...

  6. uva 12086 线段树or树状数组练习

    题目链接   https://vjudge.net/problem/34215/origin 这个题就是线段树裸题,有两种操作,实现单点更新和区间和的查找即可,这里第一次学习使用树状数组完成. 二者相 ...

  7. UVa 12299 线段树 单点更新 RMQ with Shifts

    因为shift操作中的数不多,所以直接用单点更新模拟一下就好了. 太久不写线段树,手好生啊,不是这错一下就是那错一下. PS:输入写的我有点蛋疼,不知道谁有没有更好的写法. #include < ...

  8. UVA 12299 线段树 ( 单点跟新 , 区间查询)

    题目链接:题意:在传统的RMQ的基础上加上一个操作:shift(i1,i2,i3...ik),表示将这些元素,依次向左移动一位(训练指南247页) #include <iostream> ...

  9. UVA 11992 ——线段树(区间修改)

    解题思路: 将矩阵每一行建立一棵线段树,进而变成一维问题求解.注意数组要开 4*N 代码如下: #include <iostream> #include <cstdio> #i ...

随机推荐

  1. 图片轮播,信手拈来(jquery)

    制作图片轮播,可以说是js或者jquery学习者应该掌握的技巧.但惭愧的是本菜之前一直一知半解,这回抽了半天多总结了下分享给大家.虽然标题比较吹牛,但目的是希望大家看了之后制作图片轮播会非常迅速. 首 ...

  2. gith命令行使用之上传和删除

    git这个工具的功能很强大,而使用git bash的命令行来进行git工具的操作尤为重要.而且我个人认为,用命令行进行git工具的操作比起图形界面的git工具,要更容易理解.图形界面的那个叫Torto ...

  3. c#多线程中Lock()关键字的用法小结

    本篇文章主要是对c#多线程中Lock()关键字的用法进行了详细的总结介绍,需要的朋友可以过来参考下,希望对大家有所帮助     本文介绍C# lock关键字,C#提供了一个关键字lock,它可以把一段 ...

  4. Spark计算模型RDD

    RDD弹性分布式数据集 RDD概述 RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是Spark中最基本的数据抽象,它代表一个不可变.可分区.里面的元素可并行 ...

  5. <React Native移动开发实战>-1-React Native的JSX解决方案

    JSX并不是一门新的开发语言,而是Facebook提出的语法方案:一种可以在JavaScript代码中直接书写HTML标签的语法糖,所以,JSX本质上还是JavaScript语言. 小知识:语法糖(S ...

  6. shutdown命令详解

    基础命令学习目录 原文链接:http://www.cnblogs.com/qlqwjy/p/7746364.html 我 们在操作Linux v/服务器的时候肯定会有需要重启系统,或者关闭系统等操作. ...

  7. bootstrap轮播图不能显示左右箭头

    引入font文件夹即可 原文 :http://www.imooc.com/qadetail/64277

  8. No.1010_第七次团队会议

    渺茫的前景 今天大家都很失望,一来昨天的问题还是继续存在着,仍然没有完成.二来,我们看了一下其余几个组的界面,对自己有些难过. 我们组确实存在人手少的问题,这几天我还因为挑战杯的事情缺席了两天,感觉内 ...

  9. Task 5.1 电梯调度程序需求调研报告

    1.任务概述: 1.1任务背景:试想一下,石家庄铁道大学基础教学楼的电梯配置如下:大厦有18层, 4部电梯,很多乘客使用这些电梯的日常(旅客重量:平均70公斤最大120公斤,最小45公斤).其他常量数 ...

  10. 我对git的认识

    Git 真的是不了解 也没听说过git 所以真的不知道从何谈起 所以就参考度娘啦! Git是一个开源的分布式版本控制系统,用以有效.高速的处理从很小到非常大的项目版本管理.Git 是 Linus To ...