Codeforces 484E. Sign on Fence 可持久化线段树
来源:互联网 发布:淘宝网找不到卖家中心 编辑:程序博客网 时间:2024/05/23 01:17
大概题意:
给一数组a,问在某一区间L~R中,问对于连续的长为W的一段中最小的数字的最大值是多少.
显然可以转化成二分高度然后判断可行性的问题.
考虑到高度肯定为数组中的某一个值,将数组从大到小排序. 建n棵线段树,对于第 i 棵线段树,将 大于等于a[i] 的叶子的值设置为1,其他的叶子设置为0,问题就转化成了用线段树求某一区间中最长的连续的1的个数,这是一个线段树的经典问题,可以通过维护每个节点的左边连续和,右边连续和,连续和的最大值 得到.
由于空间问题,不可能建立10^5棵线段树,考虑到相邻的两个线段树之间只有一条边的值是不一样的,可以共用其他节点来节省空间,所以建立一个可持久化线段树就可以了, 具体细节可以看代码 .
/* ***********************************************Author :CKbossCreated Time :2015年03月11日 星期三 19时18分54秒File Name :CF484E_2.cpp************************************************ */#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <string>#include <cmath>#include <cstdlib>#include <vector>#include <queue>#include <set>#include <map>using namespace std;const int maxn=100100;const int maxm=maxn*40;int n;int ch[maxm][2],leftsum[maxm],rightsum[maxm],allsum[maxm],lenth[maxm];int T[maxn],tot,res,toleft;struct Fe{int h,id;}fe[maxn];bool cmp(Fe a,Fe b){return a.h>b.h;}/// push_upvoid push_up(int rt){lenth[rt]=lenth[ch[rt][0]]+lenth[ch[rt][1]];leftsum[rt]=leftsum[ch[rt][0]];if(leftsum[ch[rt][0]]==lenth[ch[rt][0]])leftsum[rt]+=leftsum[ch[rt][1]];rightsum[rt]=rightsum[ch[rt][1]];if(rightsum[ch[rt][1]]==lenth[ch[rt][1]])rightsum[rt]+=rightsum[ch[rt][0]];allsum[rt]=max(allsum[ch[rt][0]],allsum[ch[rt][1]]);allsum[rt]=max(allsum[rt],rightsum[ch[rt][0]]+leftsum[ch[rt][1]]);}/// buildint build(int l,int r){int rt=tot++;if(l==r){leftsum[rt]=rightsum[rt]=allsum[rt]=0;lenth[rt]=1;return rt;}int m=(l+r)/2;ch[rt][0]=build(l,m);ch[rt][1]=build(m+1,r);push_up(rt);return rt;}/// insertint insert(int oldrt,int pos,int l,int r){int rt=tot++;ch[rt][0]=ch[oldrt][0];ch[rt][1]=ch[oldrt][1];if(l==pos&&r==pos){leftsum[rt]=rightsum[rt]=allsum[rt]=1;lenth[rt]=1;return rt;}int m=(l+r)/2;if(pos<=m) ch[rt][0]=insert(ch[oldrt][0],pos,l,m);else ch[rt][1]=insert(ch[oldrt][1],pos,m+1,r);push_up(rt);return rt;}/// queryvoid query(int rt,int L,int R,int l,int r){if(L<=l&&r<=R){res=max(res,allsum[rt]);toleft+=leftsum[rt];res=max(res,toleft);if(leftsum[rt]!=lenth[rt])toleft=rightsum[rt];res=max(res,toleft);return ;}int m=(l+r)/2;if(R<=m) return query(ch[rt][0],L,R,l,m);else if(L>m) return query(ch[rt][1],L,R,m+1,r);else{query(ch[rt][0],L,R,l,m);query(ch[rt][1],L,R,m+1,r);}}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout);scanf("%d",&n);for(int i=1;i<=n;i++){int x;scanf("%d",&x);fe[i].h=x; fe[i].id=i;}sort(fe+1,fe+1+n,cmp);T[0]=build(1,n);for(int i=1;i<=n;i++)T[i]=insert(T[i-1],fe[i].id,1,n);int T_T;scanf("%d",&T_T);while(T_T--){int L,R,W;scanf("%d%d%d",&L,&R,&W);int low=1,high=n,ans;while(low<=high){int mid=(low+high)/2;toleft=res=0;query(T[mid],L,R,1,n);if(res>=W){ans=mid; high=mid-1;}else low=mid+1;}printf("%d\n",fe[ans].h);} return 0;}
1 0
- Codeforces 484E Sign on Fence(可持久化线段树+二分)
- 【codeforces】484E. Sign on Fence 可持久化线段树
- Codeforces 484E. Sign on Fence 可持久化线段树
- codeforces 484E Sign on Fence 可持久化线段树+二分查找
- 可持久化线段树 CF484E-Sign on Fence
- Codeforces 484E Sign on Fence
- CodeForces 484E Sign on Fence
- codeforces 484E Sign on Fence
- 【CodeForces】484E Sign on Fence
- CF 484E Sign on Fence
- Codeforces 538F【可持久化线段树】
- [可持久化线段树] codeforces 707D. Persistent Bookcase
- 可持久化线段树
- 可持久化线段树
- 可持久化线段树
- 可持久化线段树
- 可持久化线段树
- 可持久化线段树
- ionic
- Android4.0 彻底隐藏状态栏
- 241个jquery插件—jquery插件大全
- 12年的滑雪小记
- 关闭Linux下的SELinux
- Codeforces 484E. Sign on Fence 可持久化线段树
- AngularJS初学
- 自,动,更,新
- iOS多线程之GCD——基本概念与队列(Dispatch Queue)
- oracle查询序列
- Android 自定义控件玩转字体变色 打造炫酷ViewPager指示器
- NGUI Next-Gen UIv3.5.1中Button实现点击
- 对象名 'sysproperties' 无效
- 此生错过,终是永别