题目链接:

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 (线段树+扫描线)的更多相关文章

  1. Codeforces 1108E (Array and Segments) 线段树

    题意:给你一个长度为n的序列和m组区间操作,每组区间操作可以把区间[l, r]中的数字都-1,请选择一些操作(可以都不选),使得序列的最大值和最小值的差值尽量的大. 思路:容易发现如果最大值和最小值都 ...

  2. 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 ...

  3. Codeforces Round #337 (Div. 2) D. Vika and Segments (线段树+扫描线+离散化)

    题目链接:http://codeforces.com/contest/610/problem/D 就是给你宽度为1的n个线段,然你求总共有多少单位的长度. 相当于用线段树求面积并,只不过宽为1,注意y ...

  4. Codeforces 1108E2 Array and Segments (Hard version) 差分, 暴力

    Codeforces 1108E2 E2. Array and Segments (Hard version) Description: The only difference between eas ...

  5. Codeforces 1108E2 Array and Segments (Hard version)(差分+思维)

    题目链接:Array and Segments (Hard version) 题意:给定一个长度为n的序列,m个区间,从m个区间内选择一些区间内的数都减一,使得整个序列的最大值减最小值最大. 题解:利 ...

  6. Codeforces 610D Vika and Segments 线段树+离散化+扫描线

    可以转变成上一题(hdu1542)的形式,把每条线段变成宽为1的矩形,求矩形面积并 要注意的就是转化为右下角的点需要x+1,y-1,画一条线就能看出来了 #include<bits/stdc++ ...

  7. Codeforces VK CUP 2015 D. Closest Equals(线段树+扫描线)

    题目链接:http://codeforces.com/contest/522/problem/D 题目大意:  给你一个长度为n的序列,然后有m次查询,每次查询输入一个区间[li,lj],对于每一个查 ...

  8. 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 ...

  9. hdu 1828 线段树扫描线(周长)

    Picture Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

随机推荐

  1. hdu 2846 字典树变形

    mark: 题目有字串匹配的过程 有两点 1.为了高效的匹配子串 可以把所有的子串都预处理进去 然后字典树计数就放在最后面 2.在同一个母串处理自串的时候 会有重复的时候 比如abab  这里去重用个 ...

  2. Docker 杂记

    1.配置阿里云加速 :可以找到各种加速URL.比如 https://tnxkcso1.mirror.aliyuncs.com/ 2.windows 配置: 3.docker info可以看到新的配置已 ...

  3. 【原创】大叔经验分享(80)openresty(nginx+lua)发邮件

    nginx配置 lua_package_path "/usr/local/openresty/lualib/resty/smtp/?.lua;;"; lua_need_reques ...

  4. Spark机器学习API之特征处理(一)

    Spark机器学习库中包含了两种实现方式,一种是spark.mllib,这种是基础的API,基于RDDs之上构建,另一种是spark.ml,这种是higher-level API,基于DataFram ...

  5. web储存的初级运用

    <html> <head> <meta charset="utf-8"> <title>web存储</title>< ...

  6. .net工作流引擎ccflow集成并增加自定义功能

    一.为什么需要自定义扩展 1.第三方类库已满足大部分需求,剩下的根据具体业务需求抽象成公共功能进行扩展 2.第三方呈现的web页面与原类库耦合度较高,希望在原页面上扩展而不影响原来的功能 3.在完全不 ...

  7. Java,JavaScript和ABAP通过代码取得当前代码的调用栈Callstack

    Java StackTraceElement stack[] = Thread.currentThread().getStackTrace(); System.out.println("Ca ...

  8. tensorflow保存数据为.pb格式和加载pb文件

    转自:https://blog.csdn.net/u014264373/article/details/79943389 https://blog.csdn.net/fu6543210/article ...

  9. PHP判断是否有Get参数的方法

    PHP如何判断是否有Get参数,方法很简单,一个函数就可以搞定,需要的朋友可以参考下 if(is_array($_GET)&&count($_GET)>0)//判断是否有Get参 ...

  10. Windows环境下使用uiautomatorviewer进行元素定位

    一.摘要 元素定位本篇主要介绍如何使用uiautomatorviewer,通过定位到页面上的元素,然后进行相应的点击等操作,uiautomatorviewer 是 android-sdk 自带的一个元 ...