Sign on Fence(连续的长为W的一段中最小的数字的最大值)
题目链接:http://codeforces.com/problemset/problem/484/E
题意:给你个n,n个木板都有高度,宽度都为1 ,给你两个数[l,r]和一个w,求在[l,r]区间的木板里宽度w的最大值,也就是连续的长为W的一段中最小的数字的最大值。
思路:首先想到了二分,找高度,然后就是如果对于每个木板高度,我们把大于等于i木板高度的线段树叶子设为1,其他为0,那么就肯定对于一个高度最长连续的1的值也就是维护一个线段树的和如果大于W
那么就肯定是可行的。所以是个求线段树中最长的连续的1的长度是多少的问题,这个问题要维护线段树的左边连续和,右边连续和,连续和的最大值。对高度从大到小排序,依次分别插入到n颗线段树中形成可持久化线段树(主席树),就能节省许多空间复杂度。维护起来 比较麻烦,好繁琐。。。
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#include<algorithm>
#include<map>
#include<vector>
#include<string>
#include<set>
#define ll long long
using namespace std;
const int maxn=1e5+;
int root[maxn],cnt;
struct Node{
int val;
int id;
}a[maxn];
struct node{
int l;
int r;
int len;
int left;
int right;
int sum;
}tree[maxn*];
void pushup(int cur)
{
tree[cur].len=tree[tree[cur].l].len+tree[tree[cur].r].len;
tree[cur].left=tree[tree[cur].l].left;
if(tree[tree[cur].l].left==tree[tree[cur].l].len)
tree[cur].left+=tree[tree[cur].r].left;
tree[cur].right=tree[tree[cur].r].right;
if(tree[tree[cur].r].right==tree[tree[cur].r].len)
tree[cur].right+=tree[tree[cur].l].right;
tree[cur].sum=max(tree[tree[cur].l].sum,tree[tree[cur].r].sum);
tree[cur].sum=max(tree[cur].sum,tree[tree[cur].l].right+tree[tree[cur].r].left);
}
void build(int &cur,int l,int r)
{
cur=++cnt;
if(l==r)
{
tree[cur].left=;
tree[cur].right=;
tree[cur].sum=;
tree[cur].len=;
return ;
}
int m=(l+r)>>;
build(tree[cur].l,l,m);
build(tree[cur].r,m+,r);
pushup(cur);
}
void update(int &now,int last,int l,int r,int tar)
{
tree[++cnt]=tree[last];
now=cnt;
if(l==r)
{
tree[now].left=;
tree[now].right=;
tree[now].sum=;
tree[now].len=;
return ;
}
int m=(l+r)>>;
if(tar<=m)
update(tree[now].l,tree[last].l,l,m,tar);
else
update(tree[now].r,tree[last].r,m+,r,tar);
pushup(now);
}
int query(int now,int L,int R,int l,int r)
{
if(L<=l&&r<=R)
return tree[now].sum;
int m=(l+r)>>;
if(R<=m)
return query(tree[now].l,L,R,l,m);
if(L>m)
return query(tree[now].r,L,R,m+,r);
int res=;
res=max(query(tree[now].l,L,R,l,m),query(tree[now].r,L,R,m+,r));
int ll=min(tree[tree[now].l].right,m-L+);
int rr=min(tree[tree[now].r].left,R-m);
res=max(res,ll+rr);
return res;
}
bool cmp(Node x,Node y)
{
return x.val>y.val;
}
int main()
{
int n,m;
cnt=;
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%d",&a[i].val);
a[i].id=i;
}
sort(a+,a++n,cmp);
build(root[],,n);
for(int i=;i<=n;i++)
update(root[i],root[i-],,n,a[i].id);
scanf("%d",&m);
int ans=;
while(m--)
{
int l,r,w;
scanf("%d%d%d",&l,&r,&w);
int ll=,rr=n;
while(ll<=rr)
{
int mid=(ll+rr)>>;
int res=query(root[mid],l,r,,n);
if(res>=w)
{
ans=mid;
rr=mid-;
}
else ll=mid+;
} printf("%d\n",a[ans].val);
}
return ;
}
Sign on Fence(连续的长为W的一段中最小的数字的最大值)的更多相关文章
- Codeforces 484E Sign on Fence(是持久的段树+二分法)
题目链接:Codeforces 484E Sign on Fence 题目大意:给定给一个序列,每一个位置有一个值,表示高度,如今有若干查询,每次查询l,r,w,表示在区间l,r中, 连续最长长度大于 ...
- CF&&CC百套计划4 Codeforces Round #276 (Div. 1) E. Sign on Fence
http://codeforces.com/contest/484/problem/E 题意: 给出n个数,查询最大的在区间[l,r]内,长为w的子区间的最小值 第i棵线段树表示>=i的数 维护 ...
- CF 484E - Sign on Fence
E. Sign on Fence time limit per test 4 seconds memory limit per test 256 megabytes input standard in ...
- Codeforces Round #276 (Div. 1) E. Sign on Fence 二分+主席树
E. Sign on Fence Bizon the Champion has recently finished painting his wood fence. The fence consi ...
- 【CF484E】Sign on Fence(主席树)
[CF484E]Sign on Fence(主席树) 题面 懒得贴CF了,你们自己都找得到 洛谷 题解 这不就是[TJOI&HEOI 排序]那题的套路吗... 二分一个答案,把大于答案的都变成 ...
- AC日记——Sign on Fence Codeforces 484e
E. Sign on Fence time limit per test 4 seconds memory limit per test 256 megabytes input standard in ...
- 读入一个字符串str,输出字符串str中连续最长的数字串
要求: 读入一个长度不超过256的字符串,例如“abc123defg123456789hjfs123456”.要求输出“123456789” 思路: 遍历字符串,如果是数字串则计算往后一共有多少个数字 ...
- ZT 查找字符串中连续最长的数字串
查找字符串中连续最长的数字串 有俩方法,1)比较好理解一些.2)晦涩 1) /* 功能:在字符串中找出连续最长的数字串,并把这个串的长度返回, 并把这个最长数字串付给其中一个函数参数outputstr ...
- CF484E Sign on Fence && [国家集训队]middle
CF484E Sign on Fence #include<bits/stdc++.h> #define RG register #define IL inline #define _ 1 ...
随机推荐
- Maximum Depth of Binary Tree(二叉树最大深度)
来源:https://leetcode.com/problems/maximum-depth-of-binary-tree Given a binary tree, find its maximum ...
- Java第五周作业+总结
实验三 String类的应用 实验目的 掌握类String类的使用: 学会使用JDK帮助文档: 实验内容 1.已知字符串:"this is a test of java".按要求执 ...
- 实验报告5&第七周课程总结
实验四 类的继承 实验目的 理解抽象类与接口的使用: 了解包的作用,掌握包的设计方法. 实验要求 掌握使用抽象类的方法. 掌握使用系统接口的技术和创建自定义接口的方法. 了解 Java 系统包的结构. ...
- JS之理解继承
JS之理解继承:https://segmentfault.com/a/1190000010468293 1.call继承,也叫借用构造函数.伪造对象或是经典继承.call继承回把父类的私有属性和方法继 ...
- 粉丝福利:收藏已久的Java架构资料免费送(仅限3天)
有段时间没跟各位粉丝分享编程资源福利了,看了下自己的百度网盘,就剩下这个我认为是比较好的Java架构师学习资料了,相信这套资料可以对你进阶高级工程师有帮助. Java架构师技术进阶路线图 架构技术进阶 ...
- java基础笔记(6)
xml文件的写入 通过dom生成xml文件: package com.writexml; import java.io.File; import javax.xml.parsers.DocumentB ...
- SQL查询结果列拼接成逗号分隔的字符串:group_concat
转自:SQL查询结果列拼接成逗号分隔的字符串 背景:做SQL查询时会经常需要,把查询的结果拼接成一个字符串. 解决方法: 通过 group_concat 函数 拼接的结果很长,导致拼接结果显示不全,可 ...
- 题解 AT2684 【K-City】
此题这么水,竟然发题解的这么少. 本蒟蒻也来发一篇QwQ. 题目中所谓“四条街包围一个街区”其实就是两条街之间夹一个街区而已: n条街有几条两两相邻呢?答案是n-1条: m条街有几条两两相邻呢?答案是 ...
- 洛谷 - P3803 -【模板】多项式乘法(FFT) - NTT
https://www.luogu.org/problemnew/show/P3803 看别人偏偏就是要用NTT去过.实验证明大概是这样用.求0~n的多项式和0~m的多项式的乘积.注意MAXN取值.A ...
- netserver启动时报错 "Unable to start netserver with 'IN(6)ADDR_ANY' port '12865' and family AF_UNSPEC'"
netperf启动netserver时报错 "Unable to start netserver with 'IN(6)ADDR_ANY' port '12865' and family A ...