Codeforces 460C 二分结果+线段树维护
发现最近碰到好多次二分结果的题目,上次多校也是,被我很机智的快速过了,这个思想确实非常不错。在正面求比较难处理的时候,二分结果再判断是否有效往往柳暗花明。
这个题目给定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 二分结果+线段树维护的更多相关文章
- Codeforces 1136E(转化+线段树维护)
题目传送 虽然线段树比较显然但是发现a数组并不好维护.考虑将a转化为好维护的数组b. 方法 这里我将k[1]设为0,对应着\[a[1] + k[1] <= a[2]\]不难得出\[a[i] + ...
- Codeforces 1093G题解(线段树维护k维空间最大曼哈顿距离)
题意是,给出n个k维空间下的点,然后q次操作,每次操作要么修改其中一个点的坐标,要么查询下标为[l,r]区间中所有点中两点的最大曼哈顿距离. 思路:参考blog:https://blog.csdn.n ...
- Codeforces 777E Hanoi Factory(线段树维护DP)
题目链接 Hanoi Factory 很容易想到这是一个DAG模型,那么状态转移方程就出来了. 但是排序的时候有个小细节:b相同时看a的值. 因为按照惯例,堆塔的时候肯定是内半径大的在下面. 因为N有 ...
- Codeforces GYM 100114 D. Selection 线段树维护DP
D. Selection Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Descriptio ...
- Codeforces Round #271 (Div. 2) E题 Pillars(线段树维护DP)
题目地址:http://codeforces.com/contest/474/problem/E 第一次遇到这样的用线段树来维护DP的题目.ASC中也遇到过,当时也非常自然的想到了线段树维护DP,可是 ...
- 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 ...
- [Codeforces]817F. MEX Queries 离散化+线段树维护
[Codeforces]817F. MEX Queries You are given a set of integer numbers, initially it is empty. You sho ...
- codeforces Good bye 2016 E 线段树维护dp区间合并
codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...
- 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 ...
随机推荐
- pytorc人工神经网络Logistic regression与全连接层
//2019.10.08神经网络与全连接层1.logistics regression逻辑回归的思想是将数据利用激活函数sigmoid函数转换为0-1的概率,然后定义一定的阈值0.5,大于阈值则为一类 ...
- BUAA软工第一次作业-热身
第一次作业-热身 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) (北京航空航天大学 - 计算机学院) 这个作业的要求在哪里 第一次作业-热身作业(阅读) 我在这个课程 ...
- ionic3记录之弹窗Alert
一个业务流程需要多个弹窗: 在上一个弹窗的onDidDissmiss写下一个弹窗:
- Android 用ViewFlipper实现跑马灯效果的公告提示
1.代码部分private void initViewFlipper(final HomepageListModel.Notice notice) { for (int i = 0; i < n ...
- quartz spring 实现动态定时任务
在实际项目应用中经常会用到定时任务,可以通过quartz和spring的简单配置即可完成,但如果要改变任务的执行时间.频率,废弃任务等就需要改变配置甚至代码需要重启服务器,这里介绍一下如何通过quar ...
- tomcat在windows下的监测
一些老旧的系统部署在了windwos服务器上,而且总是容易挂,新机器申请不到,只能.. %tomcat%bin下有service.bat的tomcat版本 service.bat install se ...
- [LuoguP1203][USACO1.1]P1203 Broken Necklace
Solution 这道题数据规模奇小,因此大部分人都使用了暴力搜索的方法,这也是我一开始的想法. 对于 100100%100 的数据,3≤n≤3503≤n≤3503≤n≤350 的确可以如此,但暴力搜 ...
- php 实现店铺装修2
<?php namespace Webapp\Model; use Common\Model\DataModel\FlagShopCategoryModel; use Common\Model\ ...
- leetcode206 Reverse Linked List
""" Reverse a singly linked list. Example: Input: 1->2->3->4->5->NULL ...
- 三 Hibernate持久化状态&主键生成策略
持久化类 持久化:将内存中的一个对象持久化到数据库中的过程 持久化类:Java类+映射文件.Java中一个类与数据库的表建立了映射关系,那么这个类称为持久化类. 持久化类的编写规则: 对持久化类提供一 ...