CF #535 (Div. 3) E2 Array and Segments (Hard version) 利用线段树进行区间转移
题意:
有m个区间,n个a[ i ] , 选择若干个区间,使得整个数组中的最大值和最小值的差值最小。n<=1e5,m<=300;
思路:
可以知道每个i,如果一个区间包含这个点,就让这个区间发挥作用。枚举每个i,找到最大值即可。
当然这个复杂度不对,我们可以通过线段树保存数组的最大值和最小值,每次区间在左端点发挥作用,在右端点去掉作用。
#include <algorithm>
#include <iterator>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <iomanip>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <stack>
#include <cmath>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <cassert> using namespace std;
#define lson (l , mid , rt << 1)
#define rson (mid + 1 , r , rt << 1 | 1)
#define debug(x) cerr << #x << " = " << x << "\n";
#define pb push_back
#define pq priority_queue typedef long long ll;
typedef unsigned long long ull;
//typedef __int128 bll;
typedef pair<ll ,ll > pll;
typedef pair<int ,int > pii;
typedef pair<int,pii> p3;
typedef pair<ll,int>pli;
//priority_queue<int> q;//这是一个大根堆q
//priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q
#define fi first
#define se second
//#define endl '\n'
//#define R register
#define OKC ios::sync_with_stdio(false);cin.tie(0)
#define FT(A,B,C) for(int A=B;A <= C;++A) //用来压行
#define REP(i , j , k) for(int i = j ; i < k ; ++i)
#define max3(a,b,c) max(max(a,b), c);
#define min3(a,b,c) min(min(a,b), c);
//priority_queue<int ,vector<int>, greater<int> >que; const ll mos = 0x7FFFFFFF; //
const ll nmos = 0x80000000; //-2147483648
const int inf = 0x3f3f3f3f;
const ll inff = 0x3f3f3f3f3f3f3f3f; //18
//const int mod = 1e9+7;
const double esp = 1e-;
const double PI=acos(-1.0);
const double PHI=0.61803399; //黄金分割点
const double tPHI=0.38196601; template<typename T>
inline T read(T&x){
x=;int f=;char ch=getchar();
while (ch<''||ch>'') f|=(ch=='-'),ch=getchar();
while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
return x=f?-x:x;
} /*-----------------------showtime---------------------*/ const int maxn = 1e5+;
int mx[maxn<<],mn[maxn<<],dif[maxn<<];
int lazy[maxn<<]; int a[maxn];
pii e[maxn];
void pushup(int rt){
mx[rt] = max(mx[rt<<], mx[rt<<|]);
mn[rt] = min(mn[rt<<], mn[rt<<|]);
dif[rt] = mx[rt] - mn[rt];
}
void build(int l,int r,int rt){
if(l == r){
mx[rt] = mn[rt] = a[l];
dif[rt] = mx[rt] - mn[rt];
return;
} int mid = (l + r) >> ;
build(l, mid, rt<<);
build(mid+, r, rt<<|);
pushup(rt);
}
vector<int>tmp,res;
void pushdown(int rt){
if(lazy[rt] == ) return;
lazy[rt<<] += lazy[rt];
lazy[rt<<|] += lazy[rt];
mn[rt<<] += lazy[rt];
mn[rt<<|] += lazy[rt];
mx[rt<<] += lazy[rt];
mx[rt<<|] += lazy[rt];
lazy[rt] = ;
return;
}
void update(int L, int R ,int c,int l,int r,int rt){
if(l>=L && r<=R){
mx[rt] += c;
mn[rt] += c;
lazy[rt] += c;
return;
}
pushdown(rt);
int mid = (l + r) >> ;
if(mid >= L)update(L,R,c,l,mid,rt<<);
if(mid < R)update(L,R,c,mid+,r,rt<<|);
pushup(rt);
} int main(){
int n,m;
scanf("%d%d", &n, &m);
for(int i=; i<=n; i++) scanf("%d", &a[i]);
build(,n,); for(int i=; i<=m; i++) scanf("%d%d", &e[i].fi, &e[i].se); int ans = ; for(int i=; i<=n; i++){ tmp.clear(); for(int j=; j<=m; j++){
if(e[j].fi == i){
update(e[j].fi,e[j].se,-,,n,);
}
else if(e[j].se == i-){
update(e[j].fi,e[j].se,,,n,);
}
if(e[j].fi <=i && e[j].se >= i)
tmp.pb(j);
}
int q = dif[];
if(ans < q){
ans = q;
// res.clear();
res = tmp; } } printf("%d\n", ans);
printf("%d\n", (int)res.size()); for(int i=; i<(int)res.size(); i++){
printf("%d ", res[i]);
}
puts("");
return ;
}
CF #535 (Div. 3) E2 Array and Segments (Hard version) 利用线段树进行区间转移的更多相关文章
- Codeforces Round #535 (Div. 3) E2. Array and Segments (Hard version) 【区间更新 线段树】
		
传送门:http://codeforces.com/contest/1108/problem/E2 E2. Array and Segments (Hard version) time limit p ...
 - CF E2 - Array and Segments (Hard version) (线段树)
		
题意给定一个长度为n的序列,和m个区间.对一个区间的操作是:对整个区间的数-1可以选择任意个区间(可以为0个.每个区间最多被选择一次)进行操作后,要求最大化的序列极差(极差即最大值 - 最小值).ea ...
 - E1. Array and Segments (Easy version)(暴力) &&  E2. Array and Segments (Hard version)(线段树维护)
		
题目链接: E1:http://codeforces.com/contest/1108/problem/E1 E2:http://codeforces.com/contest/1108/problem ...
 - 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 Round #496 (Div. 3) E2 - Median on Segments (General Case Edition)
		
E2 - Median on Segments (General Case Edition) 题目大意:给你一个数组,求以m为中位数的区间个数. 思路:很巧秒的转换,我们把<= m 数记为1, ...
 - POJ 1436 Horizontally Visible Segments (线段树·区间染色)
		
题意 在坐标系中有n条平行于y轴的线段 当一条线段与还有一条线段之间能够连一条平行与x轴的线不与其他线段相交 就视为它们是可见的 问有多少组三条线段两两相互可见 先把全部线段存下来 并按x ...
 - CodeForces -Codeforces Round #496 (Div. 3)  E2. Median on Segments (General Case Edition)
		
参考:http://www.cnblogs.com/widsom/p/9290269.html 传送门:http://codeforces.com/contest/1005/problem/E2 题意 ...
 - Array and Segments (Easy version) CodeForces - 1108E1 (暴力枚举)
		
The only difference between easy and hard versions is a number of elements in the array. You are giv ...
 
随机推荐
- bootstrap开发响应式网页的常用的一些 类的说明
			
1.navbar-导航条 1.navbar-fixed-top,让导航条固定显示在页面上部(注意:固定的导航条会遮住代码,解决方案,给body设置padding-top的值[大于或等于]为我们导航条的 ...
 - TCP报文指针解释,IP地址
			
三次握手TCP报文指针内容: 1.URG:紧急指针,当URG=1,表明紧急指针字段有效,告诉系统报文有紧急内容. 2.ACK: 确认指针,当ACK=1,确认号字段有效. 3.PSH:推送指针,当两个 ...
 - 实用小工具推荐 OpenWrite
			
[实用小工具推荐]给技术同学们推荐一款比较好用的工具,可以实现一稿多发,主流的技术渠道基本涵盖了:https://www.openwrite.cn/ 因为工作的关系,认识了很多做技术公众号的小伙伴,同 ...
 - 激活函数、正向传播、反向传播及softmax分类器,一篇就够了!
			
1. 深度学习有哪些应用 图像:图像识别.物体识别.图片美化.图片修复.目标检测. 自然语言处理:机器创作.个性化推荐.文本分类.翻译.自动纠错.情感分析. 数值预测.量化交易 2. 什么是神经网络 ...
 - 异步编程CompletableFuture实现高并发系统优化之请求合并
			
先说场景: 根据Redis官网介绍,单机版Redis的读写性能是12万/秒,批量处理可以达到70万/秒.不管是缓存或者是数据库,都有批量处理的功能.当我们的系统达到瓶颈的时候,我们考虑充分的压榨缓存和 ...
 - MBR和EFI启动过程
			
MBR启动过程 BIOS-->MBR(主引导记录)-->DPT(硬盘分区表)-->DBR(分区引导扇区)-->BootMgr-->BCD-->Winload.exe ...
 - MySQL数据库的安装和配置
			
MySQL数据库介绍 什么是数据库DB? DB的全称是database,即数据库的意思.数据库实际上就是一个文件集合,是一个存储数据的仓库,数据库是按照特定的格式把数据存储起来,用户可以对存储的数据进 ...
 - HBase 系列(六)——HBase Java API 的基本使用
			
一.简述 截至到目前 (2019.04),HBase 有两个主要的版本,分别是 1.x 和 2.x ,两个版本的 Java API 有所不同,1.x 中某些方法在 2.x 中被标识为 @depreca ...
 - Shell总结2
			
1.---------->>sed命令用来取指定范围行. 2.--------------->>>>“$?“返回值的用法 (1)判断命令.脚本或函数等程序是否执行成 ...
 - Linux 用户和组 权限管理 常用命令与参数
			
========================================================================== 1.基本概念: 所有者 : 一般为文件的创建者,谁 ...