bzoj5259: [Cerc2017]区间
还是很强的一个题 ORZ肉丝哥哥
对于两个相交区间,假如他们两个都是可行的,那么他们的交也可行,不然没可能两边都把它缺的补上
那么对于答案区间,向右找到第一个可行区间右端点覆盖询问区间,就是最优的
考虑扫描线,枚举右端点,对于当前还没有找到答案的询问,取左端点最大的去找答案
问题在于怎么快速判断一个区间是否可行
用max-min==R-L没有前途像我一样,要考虑其他性质
令i,i+1属于区间则对区间贡献1,假如[l,r]可行,那么它的权值就是r-l
那么开一棵线段树,表示每个位置到R的最大对数和+l,假如等于r说明是合法方案,求一下区间最大值和它的位置即可
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue> #define lc (now<<1)
#define rc (now<<1|1)
#define mid (ql+qr)/2
#define mx first
#define pos second
using namespace std;
typedef pair<int,int> pp;
const int _=1e2;
const int maxn=1e5+_;
const int fbin=(<<)+_; struct trnode{pp p;int la;}tr[*fbin];
void update(int now){tr[now].p=max(tr[lc].p,tr[rc].p);}
void pushdown(int now)
{
if(tr[now].la!=)
{
tr[lc].p.mx+=tr[now].la;tr[lc].la+=tr[now].la;
tr[rc].p.mx+=tr[now].la;tr[rc].la+=tr[now].la;
tr[now].la=;
}
}
void bt(int now,int ql,int qr)
{
tr[now].p.mx=qr;tr[now].p.pos=qr;
if(ql!=qr)
{
bt(lc,ql,mid);
bt(rc,mid+,qr);
}
}
void add(int now,int ql,int qr,int l,int r,int w)
{
if(ql==l&&qr==r){tr[now].p.mx++,tr[now].la++;return ;}
pushdown(now);
if(r<=mid) add(lc,ql,mid,l,r,w);
else if(mid+<=l)add(rc,mid+,qr,l,r,w);
else add(lc,ql,mid,l,mid,w),add(rc,mid+,qr,mid+,r,w);
update(now);
}
pp findmax(int now,int ql,int qr,int l,int r)
{
if(ql==l&&qr==r)return tr[now].p;
pushdown(now);
if(r<=mid) return findmax(lc,ql,mid,l,r);
else if(mid+<=l)return findmax(rc,mid+,qr,l,r);
else return max(findmax(lc,ql,mid,l,mid),findmax(rc,mid+,qr,mid+,r));
} int n,a[maxn],b[maxn];
struct query{int l,r,id;}q[maxn];int Q; pp as[maxn];
bool cmp(query q1,query q2){return q1.r<q2.r;}
struct cmq{bool operator()(query q1,query q2){return q1.l<q2.l;}};
priority_queue<query,vector<query>,cmq>p;
int main()
{
int n;
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&a[i]),b[a[i]]=i; scanf("%d",&Q);
for(int i=;i<=Q;i++)
scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i;
sort(q+,q+Q+,cmp); int tp=; bt(,,n);
int x;query tq;pp tt;
for(int i=;i<=n;i++)
{
if(a[i]!=)
{
x=b[a[i]-];
if(x<i)add(,,n,,x,i);
}
if(a[i]!=n)
{
x=b[a[i]+];
if(x<i)add(,,n,,x,i);
} while(tp<=n&&q[tp].r==i)p.push(q[tp]),tp++;
while(!p.empty())
{
tq=p.top();
tt=findmax(,,n,,tq.l);
if(tt.first==i)
{
as[tq.id]=make_pair(tt.pos,i);
p.pop();
}
else break;
}
} for(int i=;i<=Q;i++)printf("%d %d\n",as[i].mx,as[i].pos); return ;
}
bzoj5259: [Cerc2017]区间的更多相关文章
- BZOJ5259/洛谷P4747: [Cerc2017]区间
BZOJ5259/洛谷P4747: [Cerc2017]区间 2019.8.5 [HZOI]NOIP模拟测试13 C.优美序列 思维好题,然而当成NOIP模拟题↑真的好吗... 洛谷和BZOJ都有,就 ...
- [CERC2017]Intrinsic Interval——扫描线+转化思想+线段树
[CERC2017]Intrinsic Interval https://www.luogu.org/blog/ywycasm/solution-p4747# 这种“好的区间”,见得还是比较多的了. ...
- ASP.NET Core应用针对静态文件请求的处理[2]: 条件请求与区间请求
通过调用ApplicationBuilder的扩展方法UseStaticFiles注册的StaticFileMiddleware中间件帮助我们处理针对文件的请求.对于StaticFileMiddlew ...
- SQL Server 随机数,随机区间,随机抽取数据rand(),floor(),ceiling(),round(),newid()函数等
在查询分析器中执行:select rand(),可以看到结果会是类似于这样的随机小数:0.36361513486289558,像这样的小数在实际应用中用得不多,一般要取随机数都会取随机整数.那就看下面 ...
- codevs 1082 线段树练习 3(区间维护)
codevs 1082 线段树练习 3 时间限制: 3 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 给你N个数,有两种操作: 1:给区 ...
- codevs 1082 线段树区间求和
codevs 1082 线段树练习3 链接:http://codevs.cn/problem/1082/ sumv是维护求和的线段树,addv是标记这歌节点所在区间还需要加上的值. 我的线段树写法在运 ...
- [LeetCode] Find Right Interval 找右区间
Given a set of intervals, for each of the interval i, check if there exists an interval j whose star ...
- [LeetCode] Non-overlapping Intervals 非重叠区间
Given a collection of intervals, find the minimum number of intervals you need to remove to make the ...
- [LeetCode] Data Stream as Disjoint Intervals 分离区间的数据流
Given a data stream input of non-negative integers a1, a2, ..., an, ..., summarize the numbers seen ...
随机推荐
- 空扫描Idle Scanning
空扫描Idle Scanning 空扫描Idle Scanning是一种借助第三方实施的端口扫描技术,可以很好的隐蔽扫描主机本身.它的实现基于以下两个TCP工作机制. (1)在TCP三次握手阶 ...
- POJ 2253 Frogger Floyd
原题链接:http://poj.org/problem?id=2253 Frogger Time Limit: 1000MS Memory Limit: 65536K Total Submissi ...
- (入门SpringBoot)SpringBoot配置全局异常(五)
Spring的全局异常,用于捕获程序员没有捕获的异常.具体请看下面代码: 1.ControllerAdvice拦截异常,统一处理.通过Spring的AOP来管理. @ControllerAdvicep ...
- iOS -- 原生NSStream实现socket
- (void)startSocket:(NSString *)address andPort:(int)port { CFReadStreamRef readRef; CFWriteStreamRe ...
- Hive UDF开发-简介
Hive进行UDF开发十分简单,此处所说UDF为Temporary的function,所以需要hive版本在0.4.0以上才可以. Hive的UDF开发只需要重构UDF类的evaluate函数即可.例 ...
- serialVersionUID的作用以及如何用idea自动生成实体类的serialVersionUID
转载:http://blog.csdn.net/liuzongl2012/article/details/45168585 serialVersionUID的作用: 通过判断实体类的serialVer ...
- php empty、isset、is_null区别
有关 PHP 的 empty(),isset() 还有 is_null() 这三个函数的用法讨论得已经很多了,而且很多资料也未必能说得很清楚.这里再重复一次,但不是从概念去说,直接用程序例子来说话,应 ...
- WPF 的 MVVM
Model——View——ViewModel http://www.cnblogs.com/fdyang/p/3877309.html
- linux find prune排除某目录或文件
http://blog.csdn.net/ysdaniel/article/details/7995681 查找cache目录下不是html的文件 find ./cache ! -name '*.ht ...
- Linux的基本使用
检测某个地址是否可以通信:ping xx.xx.xx.xx 检测某个端口是否开启:telnet xx.xx.xx.xx port 端口:用来区别不同服务 常用命令: 创建一个目录 /data mkdi ...