codeforces#1108E2. Array and Segments (线段树+扫描线)
题目链接:
http://codeforces.com/contest/1108/problem/E2
题意:
给出$n$个数和$m$个操作
每个操作是下标为$l$到$r$的数减一
选出某些操作,使$n$个数的最大值减最小值最大
数据范围:
$1 \le n \le 10^5$
$0 \le m \le 300$
$-10^6 \le a_i \le 10^6$
分析:
假设选择第$i$位置作为最小值,那么我们选取所有包含$i$的区间可以得到选择第$i$位置为最小值的最佳答案
第一步,我们从$1$到$n$枚举最小值的位置
第二步,我们用扫描线来添加和减少题目给出的区间影响,例如最小值为$i$时,我们要让所有的包含i区间的操作生效
第三步,计算以$i$为最小值时的最优解
ac代码:
#include<bits/stdc++.h>
#define ll long long
#define pa pair<int,int>
using namespace std;
const int maxn=1e5+10;
const int maxm=300+10;
const ll mod=1e9+7;
int ans=-1,inde,tree[maxn*4],lazy[maxn*4],num[maxn],n;
pa quer[maxm];
vector<pa>ve[maxn];
vector<int>ve2;
void build(int st,int en,int rt)
{
if(st==en)
{
tree[rt]=num[st];
return ;
}
int md=(st+en)/2;
build(st,md,rt*2);
build(md+1,en,rt*2+1);
tree[rt]=max(tree[rt*2],tree[rt*2+1]);
}
void update(int l,int r,int x,int st,int en,int rt)
{
if(l>en||r<st)return ;
if(l<=st&&r>=en)
{
lazy[rt]+=x;
tree[rt]+=x;
return ;
}
if(lazy[rt])
{
int v=lazy[rt];
lazy[rt*2]+=v;
lazy[rt*2+1]+=v;
tree[rt*2]+=v;
tree[rt*2+1]+=v;
lazy[rt]=0;
}
int md=(st+en)/2;
update(l,r,x,st,md,rt*2);
update(l,r,x,md+1,en,rt*2+1);
tree[rt]=max(tree[rt*2],tree[rt*2+1]);
}
int Quer(int x,int st,int en,int rt)
{
if(st==en)
return tree[rt];
if(lazy[rt])
{
int v=lazy[rt];
lazy[rt*2]+=v;
lazy[rt*2+1]+=v;
tree[rt*2]+=v;
tree[rt*2+1]+=v;
lazy[rt]=0;
}
int md=(st+en)/2;
int res;
if(x<=md)res=Quer(x,st,md,rt*2);
else res=Quer(x,md+1,en,rt*2+1);
tree[rt]=max(tree[rt*2],tree[rt*2+1]);
return res;
}
int main()
{
int q;
scanf("%d %d",&n,&q);
for(int i=1;i<=n;i++)
scanf("%d",&num[i]);
build(1,n,1);
for(int i=1;i<=q;i++)
{
int l,r;
scanf("%d %d",&l,&r);
quer[i].first=l;
quer[i].second=r;
ve[l].push_back(make_pair(i,-1));
ve[r+1].push_back(make_pair(i,+1));
}
for(int i=1;i<=n;i++)
{
for(int j=0;j<ve[i].size();j++)
{
int v=ve[i][j].first;
int add=ve[i][j].second;
update(quer[v].first,quer[v].second,add,1,n,1);
}
int res=tree[1]-Quer(i,1,n,1);
if(res>ans)
{
inde=i;
ans=res;
}
}
printf("%d\n",ans);
int res=0;
for(int i=1;i<=q;i++)
if(inde>=quer[i].first&&inde<=quer[i].second)
ve2.push_back(i);
printf("%d\n",ve2.size());
for(int i=0;i<ve2.size();i++)
printf("%d%c",ve2[i]," \n"[i==ve2.size()-1]);
return 0;
}
codeforces#1108E2. Array and Segments (线段树+扫描线)的更多相关文章
- Codeforces 1108E (Array and Segments) 线段树
题意:给你一个长度为n的序列和m组区间操作,每组区间操作可以把区间[l, r]中的数字都-1,请选择一些操作(可以都不选),使得序列的最大值和最小值的差值尽量的大. 思路:容易发现如果最大值和最小值都 ...
- Codeforces Round #337 (Div. 2) D. Vika and Segments 线段树扫描线
D. Vika and Segments 题目连接: http://www.codeforces.com/contest/610/problem/D Description Vika has an i ...
- Codeforces Round #337 (Div. 2) D. Vika and Segments (线段树+扫描线+离散化)
题目链接:http://codeforces.com/contest/610/problem/D 就是给你宽度为1的n个线段,然你求总共有多少单位的长度. 相当于用线段树求面积并,只不过宽为1,注意y ...
- Codeforces 1108E2 Array and Segments (Hard version) 差分, 暴力
Codeforces 1108E2 E2. Array and Segments (Hard version) Description: The only difference between eas ...
- Codeforces 1108E2 Array and Segments (Hard version)(差分+思维)
题目链接:Array and Segments (Hard version) 题意:给定一个长度为n的序列,m个区间,从m个区间内选择一些区间内的数都减一,使得整个序列的最大值减最小值最大. 题解:利 ...
- Codeforces 610D Vika and Segments 线段树+离散化+扫描线
可以转变成上一题(hdu1542)的形式,把每条线段变成宽为1的矩形,求矩形面积并 要注意的就是转化为右下角的点需要x+1,y-1,画一条线就能看出来了 #include<bits/stdc++ ...
- Codeforces VK CUP 2015 D. Closest Equals(线段树+扫描线)
题目链接:http://codeforces.com/contest/522/problem/D 题目大意: 给你一个长度为n的序列,然后有m次查询,每次查询输入一个区间[li,lj],对于每一个查 ...
- Codeforces Round #337 (Div. 2) D. Vika and Segments 线段树 矩阵面积并
D. Vika and Segments Vika has an infinite sheet of squared paper. Initially all squares are whit ...
- hdu 1828 线段树扫描线(周长)
Picture Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
随机推荐
- @Html.ActionLink方法
Html.ActionLink:MVC提供的自动构造重写地址的方法,该方法有五个重载 1.Html.ActionLink("linkText","actionName&q ...
- MyEclipse10.0 采用插件方式安装 SVN
一.到官方上下载svn1.8.3,下载后的文件名叫site-1.8.3.zip 地址:http://subclipse.tigris.org/servlets/ProjectDocumentList? ...
- arcgis 服务网页打开需要输入用户名和密码问题解决
解决方法: 在站点manager中,检查服务的安全性,确认是否是公共.如果不是,设置为公共,面向任何人:如果服务已经被设置为面向公共,那么先设置为私有,面向所选用户,然后再设置为公共,面向任何人 如果 ...
- ThreadPoolExecutor的runState和workCount变量怎么存储?
在阅读Java线程池ThreadPoolExecutor源码的时候,发现它很巧妙地把线程池状态runState和线程数workCount两个变量存放在了一个int型变量里面. 我们先看一个数值,如下是 ...
- 面试之HTML5 Web存储
前几天面试遇到了一个题是问localStorage和sessionStorage的区别,当时的回答不是很全面,今天就针对这个问题做一下整理(概念,用法,区别) HTML5 Web存储,一个比 cook ...
- jboss 反序列化 getshell
获取信息 上传jsp 小马 小马成功 上传大马,大马也成功
- Dubbo 配置参数
关闭启动检查 在dubbo多模块项目启动的时候为了并行启动多个服务,缩短启动时间,需要解除模块之间的依赖检测 dubbo.consumer.check=false @Reference(check = ...
- 2.第一个MyBatis程序
1.导入jar包 2.定义实体类 3.创建对应的表 4.定义Dao接口 public interface StudentDAO { public void saveStudent(Student s) ...
- Java检查异常和非检查异常,运行时异常和非运行时异常的区别
通常,Java的异常(包括Exception和Error)分为检查异常(checked exceptions)和非检查的异常(unchecked exceptions).其中根据Exception异常 ...
- win10 增加一个新磁盘
1.右键我的电脑,选择管理 可以看到C盘的空间相比较大,拿出来250G的空间做成E盘 2.选择OS(C:),右键,压缩卷,请稍后,点击压缩 3.此刻会看到,有一块黑色区域就是新建的未分配空间,这时我们 ...