AC日记——Sign on Fence Codeforces 484e
4 seconds
256 megabytes
standard input
standard output
Bizon the Champion has recently finished painting his wood fence. The fence consists of a sequence of n panels of 1 meter width and of arbitrary height. The i-th panel's height is hi meters. The adjacent planks follow without a gap between them.
After Bizon painted the fence he decided to put a "for sale" sign on it. The sign will be drawn on a rectangular piece of paper and placed on the fence so that the sides of the sign are parallel to the fence panels and are also aligned with the edges of some panels. Bizon the Champion introduced the following constraints for the sign position:
- The width of the sign should be exactly w meters.
- The sign must fit into the segment of the fence from the l-th to the r-th panels, inclusive (also, it can't exceed the fence's bound in vertical direction).
The sign will be really pretty, So Bizon the Champion wants the sign's height to be as large as possible.
You are given the description of the fence and several queries for placing sign. For each query print the maximum possible height of the sign that can be placed on the corresponding segment of the fence with the given fixed width of the sign.
The first line of the input contains integer n — the number of panels in the fence (1 ≤ n ≤ 105).
The second line contains n space-separated integers hi, — the heights of the panels (1 ≤ hi ≤ 109).
The third line contains an integer m — the number of the queries (1 ≤ m ≤ 105).
The next m lines contain the descriptions of the queries, each query is represented by three integers l, r and w (1 ≤ l ≤ r ≤ n,1 ≤ w ≤ r - l + 1) — the segment of the fence and the width of the sign respectively.
For each query print the answer on a separate line — the maximum height of the sign that can be put in the corresponding segment of the fence with all the conditions being satisfied.
5
1 2 2 3 3
3
2 5 3
2 5 2
1 5 5
2
3
1
The fence described in the sample looks as follows:
The possible positions for the signs for all queries are given below.
The optimal position of the sign for the first query.The optimal position of the sign for the second query.The optimal position of the sign for the third query.
思路:
其实这题不水。
我们考虑主席树;
这个就变水了;
我们离散一下高度;
然后针对每个离散后的高度建立有n个节点的线段树;
线段树的末节点表示当前节点的高度是否大于当前离散的高度(不懂请看代码);
然后维护最大子段;
然后,每次二分高度,判断以当前高度的根的树高度是否在l~r区间满足w宽度;
然后,轻松ac(不知道wa了多少次);
来,上代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> #define maxn 100005 using namespace std; struct SequenceNodeType {
int p,hi;
};
struct SequenceNodeType point[maxn]; struct TreeNodeType {
int lc,rc,dis,ld,rd,size;
};
struct TreeNodeType tree[maxn*]; struct AnsType {
int l,r,dis,size; AnsType(int l_,int r_,int dis_,int size_)
{
l=l_,r=r_,dis=dis_,size=size_;
}
}; int if_z,n,hash[maxn],size,Pre,tot;
int li,ri,ans,x,m,root[maxn]; char Cget; inline void in(int &now)
{
now=,if_z=,Cget=getchar();
while(Cget>''||Cget<'')
{
if(Cget=='-') if_z=-;
Cget=getchar();
}
while(Cget>=''&&Cget<='')
{
now=now*+Cget-'';
Cget=getchar();
}
now*=if_z;
} bool icmp(int a,int b)
{
return a>b;
} bool cmp(SequenceNodeType a,SequenceNodeType b)
{
return a.hi>b.hi;
} void tree_build(int &now,int l,int r)
{
now=++tot;
tree[now].size=r-l+;
if(l==r) return ;
int mid=(l+r)>>;
tree_build(tree[now].lc,l,mid);
tree_build(tree[now].rc,mid+,r);
} void tree_add(int pre,int &now,int to,int l,int r)
{
now=++tot;
tree[now].size=tree[pre].size;
if(l==r)
{
tree[now].dis=,tree[now].rd=,tree[now].ld=;
return ;
}
int mid=(l+r)>>;
if(to>mid)
{
tree_add(tree[pre].rc,tree[now].rc,to,mid+,r);
tree[now].lc=tree[pre].lc;
}
else
{
tree_add(tree[pre].lc,tree[now].lc,to,l,mid);
tree[now].rc=tree[pre].rc;
}
tree[now].dis=tree[tree[now].lc].rd+tree[tree[now].rc].ld;
tree[now].dis=max(tree[now].dis,tree[tree[now].lc].dis);
tree[now].dis=max(tree[now].dis,tree[tree[now].rc].dis);
if(tree[tree[now].lc].ld==tree[tree[now].lc].size)
{
tree[now].ld=tree[tree[now].lc].size+tree[tree[now].rc].ld;
}
else tree[now].ld=tree[tree[now].lc].ld;
if(tree[tree[now].rc].rd==tree[tree[now].rc].size)
{
tree[now].rd=tree[tree[now].rc].size+tree[tree[now].lc].rd;
}
else tree[now].rd=tree[tree[now].rc].rd;
} struct AnsType tree_query(int now,int l,int r,int tl,int tr)
{
if(l==tl&&r==tr)
{
AnsType pos(tree[now].ld,tree[now].rd,tree[now].dis,tree[now].size);
return pos;
}
int mid=(l+r)>>;
if(tl>mid) return tree_query(tree[now].rc,mid+,r,tl,tr);
else if(tr<=mid) return tree_query(tree[now].lc,l,mid,tl,tr);
else
{
AnsType pos(,,,);
AnsType ll=tree_query(tree[now].lc,l,mid,tl,mid);
AnsType rr=tree_query(tree[now].rc,mid+,r,mid+,tr);
pos.size=ll.size+rr.size;
pos.dis=max(ll.dis,rr.dis);
pos.dis=max(pos.dis,ll.r+rr.l);
if(ll.size==ll.l) pos.l=ll.size+rr.l;
else pos.l=ll.l;
if(rr.size==rr.r) pos.r=rr.size+ll.r;
else pos.r=rr.r;
return pos;
}
} bool check(int now)
{
AnsType pos=tree_query(root[now],,n,li,ri);
int ans_=max(pos.dis,max(pos.l,pos.r));
if(ans_>=x) return true;
else return false;
} int find(int pos)
{
int l=,r=size,mid;
while(l<r)
{
mid=(l+r)>>;
if(hash[mid]==pos) return mid;
if(pos>hash[mid]) r=mid-;
else l=mid+;
}
return l;
} int main()
{
in(n);
for(int i=;i<=n;i++)
{
point[i].p=i;
in(point[i].hi);
hash[i]=point[i].hi;
}
sort(hash+,hash+n+,icmp);
sort(point+,point+n+,cmp);
size=unique(hash+,hash+n+)-hash-;
tree_build(root[],,n);Pre=root[];
for(int i=;i<=n;i++)
{
int to=find(point[i].hi);
tree_add(Pre,root[to],point[i].p,,n);Pre=root[to];
}
in(m);
while(m--)
{
in(li),in(ri),in(x);
int mid,l=,r=size;
while(l<=r)
{
mid=(l+r)>>;
if(check(mid)) ans=mid,r=mid-;
else l=mid+;
}
printf("%d\n",hash[ans]);
}
return ;
}
AC日记——Sign on Fence Codeforces 484e的更多相关文章
- Sign on Fence CodeForces - 484E
http://codeforces.com/problemset/problem/484/E 题意: 给定一个长度为n的数列,有m次询问,询问形如l r k 要你在区间[l,r]内选一个长度为k的区间 ...
- AC日记——Dynamic Problem Scoring codeforces 807d
Dynamic Problem Scoring 思路: 水题: 代码: #include <cstdio> #include <cstring> #include <io ...
- AC日记——Sagheer, the Hausmeister codeforces 812b
812B - Sagheer, the Hausmeister 思路: 搜索: 代码: #include <cstdio> #include <cstring> #includ ...
- AC日记——Sagheer and Crossroads codeforces 812a
812A - Sagheer and Crossroads 思路: 模拟: 代码: #include <cstdio> #include <cstring> #include ...
- AC日记——Is it rated? codeforces 807a
Is it rated? 思路: 水题: 代码: #include <cstdio> #include <cstring> using namespace std; ],b[] ...
- Ac日记——Distances to Zero codeforces 803b
803B - Distances to Zero 思路: 水题: 代码: #include <cstdio> #include <cstring> #include <i ...
- AC日记——Mice and Holes codeforces 797f
797F - Mice and Holes 思路: XXYXX: 代码: #include <cmath> #include <cstdio> #include <cst ...
- AC日记——Roma and Poker codeforces 803e
803E - Roma and Poker 思路: 赢或输或者平的序列: 赢和平的差的绝对值不得超过k: 结束时差的绝对值必须为k: 当“?”时可以自己决定为什么状态: 输出最终序列或者NO: dp( ...
- AC日记——Periodic RMQ Problem codeforces 803G
G - Periodic RMQ Problem 思路: 题目给一段序列,然后序列复制很多次: 维护序列很多次后的性质: 线段树动态开点: 来,上代码: #include <cstdio> ...
随机推荐
- Linux基础学习-网络管理
Linux系统网络管理NetworkManager 1 启动网络管理服务和开机自启动 在rhel7中网路管理相关命令nmcli,nmtui,nmtui-edit,nm-connection-edito ...
- 小谈python里 列表 的几种常用用法
在python中列表的常用方法主要包括增加,删除,查看和修改.下面以举例子的方法具体说明,首先我们创建两个列表,列表是用[ ]表示的,里面的元素用逗号隔开. a=[‘hello’,78,15.6,‘你 ...
- arm页表在linux中的融合
参考:arm-linux内存页表创建 arm的第一级页表条目数为4096个,对于4K页第二级目录条目个数为256个,一级二级条目都是每个条目4字节. 在linux下二级分页如下:虚拟地址——> ...
- centos7 安全配置
CentOS是最多人用来运行服务器的 Linux 版本,最新版本是 CentOS 7.当你兴趣勃勃地在一台主机或 VPS 上安装 CentOS 7 后,首要的工作肯定是加强它的安全性,以下列出的七件事 ...
- PAT Basic 1073
1073 多选题常见计分法 批改多选题是比较麻烦的事情,有很多不同的计分方法.有一种最常见的计分方法是:如果考生选择了部分正确选项,并且没有选择任何错误选项,则得到 50% 分数:如果考生选择了任何一 ...
- Setting title-center on "< h1> " element on Android does not work, fix
app.scss: h1.title-center{ text-align: center!important; }
- 《Scrum实战》第0次课【如何学习敏捷】全团课后任务汇总
<Scrum实战>第0次课作业 完成情况: 课程名称:如何学习敏捷 1组 孟帅 孟帅: http://www.cnblogs.com/mengshuai1982/p/7096338.htm ...
- 元类相关(type & metaclass)
metaclass作用: 1) 拦截类的创建 2) 修改类 3) 返回修改之后的类 """为什么要用metaclass类而不是函数? 由于__metaclass__可以接 ...
- bootstrap里的fileimput的小问题
fileinput 是bootstrap 里面一个非常好的插件 于是我很开心的开始的使用了 $("#file_upload").fileinput({ uploadUrl: &qu ...
- python学习-- for和if结合使用
for和if结合使用: <h1> {% for i in contents %} {{ i }}{# 注意i也要用两个大括号 #} {% endfor %} </h1> < ...