发现最近碰到好多次二分结果的题目,上次多校也是,被我很机智的快速过了,这个思想确实非常不错。在正面求比较难处理的时候,二分结果再判断是否有效往往柳暗花明。

这个题目给定n个数字的序列,可以操作m次,每次要操作w个连续的数字,每次的操作将使得该段连续数字的数都+1,最后求整个序列最小值的最大值

求最小值最大,明显的二分结果的题目,我一开始还是在ACdream那个群里看到这个题,说是二分+线段树的题目,我就来做了一下。。首先二分部分很容易,下界就是初始序列的最小值,上界就是 下界+m,至于怎么判断这个就要想一下,我一开始还觉得不用线段树,因为我每次枚举完结果,对整个序列扫一遍,对不符合要求的数+到正好符号要求不就行了。

不过这个里面因为是要+连续一段,你普通的找到一个不符合条件的数,然后对他以及他之后的w-1个数都进行一次加法,很耗时啊,所以这个就是为什么要用线段树,其实我觉得用扫描线估计也可以,对某个起始点设置+1,起始点+w-1设置为-1,然后用个东西维护,++--的,估计也可以。反正最后用的线段树,普通的区间增,单点查询。

一开始还担心复杂度,不过还行的感觉,每次二分都要重新建树,这里就是 logN*N*logN,对二分结果进行判断,需要单点查询以及区间更新,这里是2*logN*logN,所以总的就是

logN*logN*(N+2)的复杂度,N最大为10的五次方,logN不超过20

#include <iostream>
#include <cstdio>
#include <cstring>
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define LL __int64
using namespace std;
const int N = 100000+10;
int n,m,w;
LL d[N<<2],flag[N<<2],A[N];
LL mini;
void up(int rt)
{
d[rt]=min(d[rt<<1],d[rt<<1|1]);
}
void build(int rt,int l,int r)
{
flag[rt]=0;
if (l>=r){
d[rt]=A[l];
//cout<<l<<" "<<A[l]<<endl;
return;
}
int mid=(l+r)>>1;
build(lson);
build(rson);
up(rt);
}
void pushdown(int rt,int l,int r)
{
if (flag[rt]==0) return;
d[rt<<1]+=flag[rt];
d[rt<<1|1]+=flag[rt];
flag[rt<<1]+=flag[rt];
flag[rt<<1|1]+=flag[rt];
flag[rt]=0;
}
LL query(int loc,int rt,int l,int r)
{
if (l==r) return d[rt];
int mid=(l+r)>>1;
pushdown(rt,l,r);
if (loc<=mid) return query(loc,lson);
else return query(loc,rson);
}
void update(LL val,int L,int R,int rt,int l,int r)
{
if (L<=l && r<=R){
d[rt]+=val;
flag[rt]+=val;
return;
}
pushdown(rt,l,r);
int mid=(l+r)>>1;
if (L<=mid) update(val,L,R,lson);
if (R>mid) update(val,L,R,rson);
up(rt);
}
bool judge(LL x)
{
LL tmp=m;
for (int i=1;i<=n;i++){
LL now=query(i,1,1,n);
// cout<<"Test "<<i<<endl;
// cout<<now<<endl;
if (now<x){
if (x-now>tmp) return 0;
else {
update(x-now,i,min(i+w-1,n),1,1,n);
tmp-=x-now;
}
}
}
return 1;
}
int main()
{
while (scanf("%d%d%d",&n,&m,&w)!=EOF)
{
mini=-1;
for (int i=1;i<=n;i++){
scanf("%I64d",&A[i]);
//cout<<i<<" "<<A[i]<<endl;
if (mini==-1) mini=A[i];
else mini=min(A[i],mini);
}
LL L=mini,R=mini+(LL)m,mid;
while (L<R){
build(1,1,n);
mid=R-(R-L)/2;
// cout<<L<<" "<<mid<<" "<<R<<endl;
if (judge(mid)) {L=mid;}
else {R=mid-1;}
}
printf("%I64d\n",L);
}
return 0; }

  

Codeforces 460C 二分结果+线段树维护的更多相关文章

  1. Codeforces 1136E(转化+线段树维护)

    题目传送 虽然线段树比较显然但是发现a数组并不好维护.考虑将a转化为好维护的数组b. 方法 这里我将k[1]设为0,对应着\[a[1] + k[1] <= a[2]\]不难得出\[a[i] + ...

  2. Codeforces 1093G题解(线段树维护k维空间最大曼哈顿距离)

    题意是,给出n个k维空间下的点,然后q次操作,每次操作要么修改其中一个点的坐标,要么查询下标为[l,r]区间中所有点中两点的最大曼哈顿距离. 思路:参考blog:https://blog.csdn.n ...

  3. Codeforces 777E Hanoi Factory(线段树维护DP)

    题目链接 Hanoi Factory 很容易想到这是一个DAG模型,那么状态转移方程就出来了. 但是排序的时候有个小细节:b相同时看a的值. 因为按照惯例,堆塔的时候肯定是内半径大的在下面. 因为N有 ...

  4. Codeforces GYM 100114 D. Selection 线段树维护DP

    D. Selection Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Descriptio ...

  5. Codeforces Round #271 (Div. 2) E题 Pillars(线段树维护DP)

    题目地址:http://codeforces.com/contest/474/problem/E 第一次遇到这样的用线段树来维护DP的题目.ASC中也遇到过,当时也非常自然的想到了线段树维护DP,可是 ...

  6. Codeforces 834D The Bakery【dp+线段树维护+lazy】

    D. The Bakery time limit per test:2.5 seconds memory limit per test:256 megabytes input:standard inp ...

  7. [Codeforces]817F. MEX Queries 离散化+线段树维护

    [Codeforces]817F. MEX Queries You are given a set of integer numbers, initially it is empty. You sho ...

  8. codeforces Good bye 2016 E 线段树维护dp区间合并

    codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...

  9. Codeforces Round #343 (Div. 2) D. Babaei and Birthday Cake 线段树维护dp

    D. Babaei and Birthday Cake 题目连接: http://www.codeforces.com/contest/629/problem/D Description As you ...

随机推荐

  1. 「ZJOI2006」物流运输

    题目 [内存限制:$256MiB$][时间限制:$1000ms$] [标准输入输出][题目类型:传统][评测方式:文本比较] [题目描述] 物流公司要把一批货物从码头 A 运到码头 B.由于货物量比较 ...

  2. js 跳转 XSS漏洞 预防

    参考:https://blog.csdn.net/qq_27446553/article/details/52433375 1.a href="_blank" 添加属性 rel=& ...

  3. VueCli3 项目结构和具体作用

  4. xcode 6 如何将 模拟器(simulator) for iphone/ipad 转变成 simulator for iphone

    xcode 6默认模拟器是iphone/ipad通用的,如果想只针对iphone或者ipad可以进行如下设置: 1.修改模拟器大小(非必须) 模拟器->WIndow->scale-> ...

  5. Mixin类的实现

    python类的多重继承由于C3算法的原因导致实现时需要提前规划先后顺序才能正常使用. 这会让人在python中使用多重继承时感到十分的麻烦. 而Mixin类则为我们带来了自由的多重继承和插拔式的舒适 ...

  6. 使用onclick报SyntaxError: identifier starts immediately after numeric literal

    少了‘’ 错误 onclick="onlineWatch(${row.title})" 正确 onclick="onlineWatch('${row.title}')&q ...

  7. 五 Hibernate的其他API,Query&Criteria&SQLQuery

    Query Criteria SQLQuery Query接口:用于接收HQL,用于查询多个对象 HQL:Hibernate Query Language  Query条件查询: Query分页查询: ...

  8. 题解 loj2065 「SDOI2016」模式字符串

    点分治. 考虑经过当前分治中心\(u\)的点对数量. 这种数点对数的问题,有一个套路.我们可以依次考虑\(u\)的每个儿子,看用当前的儿子,能和之前已经考虑过的所有儿子,组成多少点对.这样所有合法的点 ...

  9. metasploit练习

    复现ms08_067_netapi 使用模块 msf5 > use exploit/windows/smb/ms08_067_netapi 查看配置 msf5 exploit(windows/s ...

  10. Adapter之spinner

    前言: 在写代码当中有时候会用到下拉列表,下面我们讲一下spinner 正文: 因为比较简单,和之前的listView很像,所以直接上代码 <Spinner android:layout_wid ...