HDU 4831 Scenic Popularity (段树)
Scenic Popularity
假设全部景点区和歇息区都是X轴直线上的一系列顶点,所相应的坐标Xi 保证唯一。每一个景点区有个初始的热度值,而一个歇息区(坐标为Xi)的热度值等于离它距离近期的景点区Xj的热度值(距离定义为|Xi-Xj|)。假设此歇息区与两个景点区的距离一样。则歇息区的热度值选择两个景点区中的热度值最大值。假设两个热度值都一样,则任意选择当中一个。
度度熊在出门之前会常常去查看百度地图,每次查看前会有某些景点区的热度值已发生改变,从而也会导致周围的歇息区的热度值发生改变,然后度度熊想知道当前热度值<=Rk的顶点(包含景点区和歇息区)有多少个
每一个Case的第一行是N(0<N<=10000),表示景点区和歇息区的总数。
接着会有N行数据,每一列首先是顶点的X坐标Xi (0< Xi <=1e8),第二列是一个整数Hi(0=<Hi <=100000),假设Hi 不为0。则表示当前顶点为风景区且初始的热度值为Hi,否则表示当前顶点为歇息区。这N行数据会依照坐标Xi递增的方式依次给出。
接着的一行数据是操作的次数K(K<=100),最后会有K行数据,每一行的第一列要么是’U’或者’Q’,’U’表示当前操作为更改热度操作。’Q’表示当前操作为查询操作。假设是更改操作,接着会有两列数据,各自是热度值要改变的风景区的下标Lk(0<=Lk<N)以及改变后的热度值Vk(0< Vk<=100000);假设是查询操作,第二列是要查询的热度范围Rk(0< Rk<=100000)
1
4
10 0
20 3
30 0
40 2
3
Q 3
U 3 4
Q 3
Case #1:
4
2
题目大意:
T组測试数据,每组首先一个n表示 旅游区和歇息区 共同拥有 n个。
接下来是n行介绍,每行两个数字,第一个表示位置。第二个表示热度,假设热度为0表示歇息区。否则为景区。歇息区的热度与近期景区的热度同样,假设(左边和右边)两个景区距离同样。歇息区的热度取热度高的。
经接着m,表示m组询问,Q x 。表示 热度小于等于x的有多少个。
U 表示改变某个景区的热度。
解题思路:
对于Q操作的询问,非常明显是维护的一个前缀和,因此想到用线段树维。可是U操作非常复杂。要维护差量计算。
解题代码:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <algorithm>
using namespace std; const int maxn=110000;
int pos[maxn],value[maxn],lson[maxn],rson[maxn],n; struct node{
int l,r,sum;
}a[maxn*4]; void build(int l,int r,int k){
a[k].l=l;
a[k].r=r;
a[k].sum=0;
if(l<r){
int mid=(l+r)/2;
build(l,mid,2*k);
build(mid+1,r,2*k+1);
}
} void insert(int l,int r,int k,int c){
//if(k==1) cout<<"insert:"<<l<<" "<<r<<" "<<c<<" "<<endl;
if(l<=a[k].l && a[k].r<=r){
a[k].sum+=c;
}else{
int mid=(a[k].l+a[k].r)/2;
if(r<=mid) insert(l,r,2*k,c);
else if(l>=mid+1) insert(l,r,2*k+1,c);
else{
insert(l,mid,2*k,c);
insert(mid+1,r,2*k+1,c);
}
a[k].sum=a[2*k].sum+a[2*k+1].sum;
}
} int query(int l,int r,int k){
if(l<=a[k].l && a[k].r<=r){
return a[k].sum;
}else{
int mid=(a[k].l+a[k].r)/2;
if(r<=mid) return query(l,r,2*k);
else if(l>=mid+1) return query(l,r,2*k+1);
else return query(l,mid,2*k)+query(mid+1,r,2*k+1);
}
} void findlson(int k){
if(k<=0) lson[k]=-1;
else{
if(value[k-1]==0) lson[k]=lson[k-1];
else lson[k]=k-1;
}
} void findrson(int k){
if(k>=n-1) rson[k]=-1;
else{
if(value[k+1]==0) rson[k]=rson[k+1];
else rson[k]=k+1;
}
} void input(){
build(0,110000,1);
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d%d",&pos[i],&value[i]);
lson[i]=-1;
rson[i]=-1;
}
for(int i=0;i<n;i++){
if(value[i]==0) findlson(i);
}
for(int i=n-1;i>=0;i--){
if(value[i]==0) findrson(i);
}
for(int i=0;i<n;i++){
if(value[i]==0){
if( lson[i]==-1 && rson[i]==-1 ) insert(0,0,1,1);
if( lson[i]!=-1 && rson[i]==-1 ) insert(value[lson[i]],value[lson[i]],1,1);
if( lson[i]==-1 && rson[i]!=-1 ) insert(value[rson[i]],value[rson[i]],1,1);
if( lson[i]!=-1 && rson[i]!=-1 ){
int l0=lson[i],r0=rson[i];
if(pos[i]-pos[l0] <pos[r0]-pos[i] ) insert(value[l0],value[l0],1,1);
else if(pos[i]-pos[l0] > pos[r0]-pos[i] ) insert(value[r0],value[r0],1,1);
else{
insert(max(value[r0],value[l0]),max(value[r0],value[l0]),1,1);
}
}
}else{
insert(value[i],value[i],1,1);
}
}
} void solve(){
int m;
scanf("%d",&m);
while(m-- >0){
char ch;
cin>>ch;
if(ch=='Q'){
int c;
scanf("%d",&c);
cout<<query(0,c,1)<<endl;
}else{
int k,c;
scanf("%d%d",&k,&c);
insert(c,c,1,1);
insert(value[k],value[k],1,-1);
if(value[k]!=c){
for(int i=k-1;i>=0;i--){
if(value[i]!=0) continue;
if(rson[i]!=k) break;
if(lson[i]==-1){
insert(c,c,1,1);
insert(value[k],value[k],1,-1);
}else{
int l0=lson[i],r0=rson[i];
if(pos[i]-pos[l0] > pos[r0]-pos[i] ){
insert(c,c,1,1);
insert(value[k],value[k],1,-1);
}
if(pos[i]-pos[l0] == pos[r0]-pos[i] ){
insert( max(value[r0],value[l0]) , max(value[r0],value[l0]) ,1,-1);
insert( max(c,value[l0]) , max(c,value[l0]) ,1,1);
}
}
}
for(int i=k+1;i<n;i++){
if(value[i]!=0) continue;
if(lson[i]!=k) break;
if(rson[i]==-1){
insert(c,c,1,1);
insert(value[k],value[k],1,-1);
}else{
int l0=lson[i],r0=rson[i];
if(pos[i]-pos[l0] < pos[r0]-pos[i] ){
insert(c,c,1,1);
insert(value[k],value[k],1,-1);
}
if(pos[i]-pos[l0] == pos[r0]-pos[i] ){
insert( max(value[r0],value[l0]) , max(value[r0],value[l0]) ,1,-1);
insert( max(c,value[r0]) , max(c,value[r0]) ,1,1);
}
}
}
}
value[k]=c;
}
}
} int main(){
int t;
scanf("%d",&t);
for(int i=1;i<=t;i++){
input();
printf("Case #%d:\n",i);
solve();
}
return 0;
}
版权声明:本文博客原创文章。博客,未经同意,不得转载。
HDU 4831 Scenic Popularity (段树)的更多相关文章
- hdu 4831 Scenic Popularity(模拟)
pid=4831" style="font-weight:normal">题目链接:hdu 4831 Scenic Popularity 题目大意:略. 解题思路: ...
- HDU 4831 Scenic Popularity
Scenic Popularity Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- 2014百度之星初赛第二场hdu 4831 Scenic Popularity
Scenic Popularity Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- HDU 6315.Naive Operations-线段树(两棵树合并)(区间单点更新、区间最值、区间求和)+思维 (2018 Multi-University Training Contest 2 1007)
6315.Naive Operations 题意很好理解,但是因为区间求和求的是向下取整的a[i]/b[i],所以直接分数更新区间是不对的,所以反过来直接当a[i]==b[i]的时候,线段树对应的位置 ...
- HDU ACM 4578 Transformation->段树-间隔的变化
分析:复杂的经营分部树. 只有一个查询操作,这是要求[l,r]的数量之间p钍总和.并不是所有的查询所有节点,会议TLE.最好的是查询部件[a.b].所有这个区间值我们是平等的,即能返回(b-a+1)* ...
- hdu 4107当卡段树
其核心思想是记录最大的节点值和最低值,假设max<p要么min>=p时间,在节点只变化add值,不要子树遍历:否则,就往子树递归. #include<iostream> #in ...
- HDU 1394 Minimum Inversion Number (数据结构-段树)
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...
- HDU 6356.Glad You Came-线段树(区间更新+剪枝) (2018 Multi-University Training Contest 5 1007)
6356.Glad You Came 题意就是给你一个随机生成函数,然后从随机函数里确定查询的左右区间以及要更新的val值.然后最后求一下异或和就可以了. 线段树,区间最大值和最小值维护一下,因为数据 ...
- HDU 5649.DZY Loves Sorting-线段树+二分-当前第k个位置的数
DZY Loves Sorting Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Oth ...
随机推荐
- js你真的了解offsetWidth吗
offsetWidth是什么? 答:它可以获取物体宽度的数值 那么就只是这样吗! html部分 <div id="div1"></div> <styl ...
- Streak OpenCart 商城自适应主题模板 ABC-0010
兼容浏览器 IE9, Firefox, Safari, Opera, Chrome OpenCart版本号 OpenCart 1.5.x, OpenCart 1.5.6.x, OpenCart 1.5 ...
- HR筒子说:程序猿面试那点事(转)
小屁孩曾经有过4年的招聘经验,期间见识了各种类型的程序猿:有大牛.有菜牛:有功成名就,有苦苦挣扎不知方向.等后来做了一枚程序猿之后发现,HR眼中的程序猿和程序猿中的HR都是不一样的.有感与此,从HR的 ...
- docker-gitlab(转)
Issues Docker is a relatively new project and is active being developed and tested by a thriving com ...
- (2) 用DPM(Deformable Part Model,voc-release4.01)算法在INRIA数据集上训练自己的人体检測模型
步骤一,首先要使voc-release4.01目标检測部分的代码在windows系统下跑起来: 參考在window下执行DPM(deformable part models) -(检測demo部分) ...
- 使用axis公布weblogic(一个)
1.在MyEclipse创建一个新的Web Project.新类,声明函数名称.参数,为了不写功能实体. 2.将java2wsdl.bat将文件复制到classes目录,据内部参数更改自己的实际情况 ...
- Oracle FGA审计记录的清理步骤
注意:本文为原创文章,转载请注明出处: http://blog.csdn.net/msdnchina/article/details/38435999 一.确认有哪些fga审计策略, 从select ...
- CSS——(2)与标准流盒模型
部分博客<CSS--(1)基础>中简介了CSS的概念和几种用法,如今主要是介绍其的核心内容. 盒子模型 为了理解盒子模型,我们能够先从生活中的盒子入手.盒子是用来放置物品的,内部除了有物品 ...
- std::list.pop_back() 弹空了列表导致的崩溃
core文件输出: (gdb) bt # # ) at xxxxx/sql/signal_handler.cc: # <signal handler called> # # # # # 0 ...
- 第七章——DMVs和DMFs(4)——用DMV和DMF监控磁盘IO
原文:第七章--DMVs和DMFs(4)--用DMV和DMF监控磁盘IO 前言: 本文为本系列最后一篇,作为DBA,你必须经常关注磁盘的I/O问题,一旦出现问题,要尽快分析出是什么问题.SQLServ ...