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/E2
题目大意:
给你n个数,然后给你m个区间,每一个区间代表将给定的n个数这个区间内都减去1,每个区间最多使用一次。然后问你使用哪些区间能够使得这n个数中最大数和最小的差值最大?
首先对于E1:这么小的数据不暴力搞啥??直接问枚举就完事了,每一次枚举的时候保持一个数不变,假设当前的数是最大的,然后其他的只要是不包含这个数的区间,都减去,这样就能让最小的那个位置尽可能的小了。
AC代码:
#include<bits/stdc++.h>
using namespace std;
# define ll long long
# define inf 0x3f3f3f3f
const int maxn = +;
int a[maxn],b[maxn],sto[maxn];
struct node
{
int le;
int ri;
} q[maxn];
int main()
{
int n,m;
scanf("%d %d",&n,&m);
for(int i=; i<=n; i++)
{
scanf("%d",&a[i]);
}
for(int i=; i<=m; i++)
{
scanf("%d %d",&q[i].le,&q[i].ri);
}
int maxx=-inf,id=;
for(int i=; i<=n; i++)
{
int t1=-inf,t2=inf;
for(int j=; j<=n; j++)
{
b[j]=a[j];
}
for(int j=; j<=m; j++)
{
if(i>=q[j].le&&i<=q[j].ri)
continue;
for(int k=q[j].le; k<=q[j].ri; k++)
{
b[k]-=;
}
}
for(int j=; j<=n; j++)
{
t1=max(t1,b[j]);
t2=min(t2,b[j]);
}
if(t1-t2>maxx)
{
maxx=t1-t2;
id=i;
}
}
// cout<<m<<endl;
printf("%d\n",maxx);
int num=;
// cout<<1<<" "<<num<<endl;
for(int i=; i<=m; i++)
{
if(id>=q[i].le&&id<=q[i].ri)
continue;
// cout<<1<<endl;
sto[++num]=i;
}
// cout<<2<<" "<<num<<endl;
printf("%d\n",num);
for(int i=; i<=num; i++)
{
if(i==)
printf("%d",sto[i]);
else
printf(" %d",sto[i]);
}
printf("\n");
return ;
}
其次对于E2:我们可以寻找最小的数的位置,这个时候为什么不和E1一样去找最大的数的位置呢?因为我们要利用区间的性质,对于每一个节点,我们需要从第一个位置开始。
对于当枚举到第i个节点的时候,需要把包括i的区间都给整上,这个时候求一下最值之差,当枚举到第i+1个节点的时候,我们只需要把不包括第i个节点但是包括第i+1个节点的区间给整上就可以了,这样就能省去很多不必要的操作了。
AC代码:
#include<bits/stdc++.h>
using namespace std;
# define ll long long
# define inf 0x3f3f3f3f
# define lson l,m,rt<<
# define rson m+,r,rt<<|
const int maxn = 1e5+;
int minn[maxn<<],maxx[maxn<<],dif[maxn<<];
int lazy[maxn<<];
struct node
{
int le;
int ri;
} edge[+];
int sto[maxn];
int ans1,ans2;
vector<int>q1[maxn],q2[maxn];
void up(int rt)
{
minn[rt]=min(minn[rt<<],minn[rt<<|]);
maxx[rt]=max(maxx[rt<<],maxx[rt<<|]);
dif[rt]=maxx[rt]-minn[rt];// 本来查找最值得差的时候是直接询问到底部的,加了这个就不需要了,学到了!!
}
void build(int l,int r,int rt)
{
if(l==r)
{
int tmp;
scanf("%d",&tmp);
minn[rt]=tmp;
maxx[rt]=tmp;
return ;
}
int m=(l+r)>>;
build(lson);
build(rson);
up(rt);
}
void down(int rt)
{
if(lazy[rt])
{
lazy[rt<<]+=lazy[rt];
lazy[rt<<|]+=lazy[rt];
minn[rt<<]+=lazy[rt];
minn[rt<<|]+=lazy[rt];
maxx[rt<<]+=lazy[rt];
maxx[rt<<|]+=lazy[rt];
lazy[rt]=;
}
}
void update(int l,int r,int rt,int L,int R,int p)
{
if(L<=l&&R>=r)
{
minn[rt]+=p;
maxx[rt]+=p;
lazy[rt]+=p;
return ;
}
down(rt);
int m=(l+r)>>;
if(L<=m)
update(lson,L,R,p);
if(R>m)
update(rson,L,R,p);
up(rt);
}
//int querymax(int l,int r,int rt)
//{
// if(l==r)
// {
// return maxx[rt];
// }
// int t1;
// down(rt);
// int m=(l+r)>>1;
// if(l<=m)querymax(lson);
// if(r>m)querymax(rson);
// up(rt);
//}
//void querymin(int l,int r,int rt)
//{
// if(l==r)
// {
// ans2=min(ans2,minn[rt]);
// return ;
// }
// down(rt);
// int m=(l+r)>>1;
// querymin(lson);
// querymin(rson);
// up(rt);
//}
int main()
{
int n,m,tmp,len;
scanf("%d %d",&n,&m);
build(,n,);
int ans=-inf,id=;
for(int i=; i<=m; i++)
{
scanf("%d %d",&edge[i].le,&edge[i].ri);
q1[edge[i].le].push_back(i);
q2[edge[i].ri].push_back(i);
}
for(int i=; i<=n; i++)
{
len=q2[i-].size();
for(int j=; j<len; j++)
{
tmp=q2[i-][j];
update(,n,,edge[tmp].le,edge[tmp].ri,);
}
len=q1[i].size();
for(int j=; j<len; j++)
{
tmp=q1[i][j];
update(,n,,edge[tmp].le,edge[tmp].ri,-);
}
if(ans<dif[])
{
ans=dif[];
id=i;
}
}
int num=;
printf("%d\n",ans);
for(int i=; i<=m; i++)
{
if(edge[i].le<=id&&edge[i].ri>=id)
{
sto[++num]=i;
}
}
printf("%d\n",num);
for(int i=; i<=num; i++)
{
if(i==)
printf("%d",sto[i]);
else
printf(" %d",sto[i]);
}
printf("\n");
return ;
}
E1. Array and Segments (Easy version)(暴力) && E2. Array and Segments (Hard version)(线段树维护)的更多相关文章
- Light oj-1100 - Again Array Queries,又是这个题,上次那个题用的线段树,这题差点就陷坑里了,简单的抽屉原理加暴力就可以了,真是坑~~
1100 - Again Array Queries ...
- HDU - 4366 Successor DFS序 + 分块暴力 or 线段树维护
给定一颗树,每个节点都有忠诚和能力两个参数,随意指定一个节点,要求在它的子树中找一个节点代替它,这个节点要满足能力值大于它,而且是忠诚度最高的那个. 首先,dfs一下,处理出L[i], R[i]表示d ...
- CF719E. Sasha and Array [线段树维护矩阵]
CF719E. Sasha and Array 题意: 对长度为 n 的数列进行 m 次操作, 操作为: a[l..r] 每一项都加一个常数 C, 其中 0 ≤ C ≤ 10^9 求 F[a[l]]+ ...
- Codeforces Round #373 (Div. 2) E. Sasha and Array 线段树维护矩阵
E. Sasha and Array 题目连接: http://codeforces.com/contest/719/problem/E Description Sasha has an array ...
- 线段树维护矩阵【CF718C】 Sasha and Array
Description 有一个长为\(n\)的数列\(a_{1},a_{2}...a_{n}\),你需要对这个数列维护如下两种操作: \(1\space l \space r\space x\) 表示 ...
- CF718C Sasha and Array(线段树维护矩阵)
题解 (不会矩阵加速的先去学矩阵加速) 反正我想不到线段树维护矩阵.我太菜了. 我们在线段树上维护一个区间的斐波那契的列矩阵的和. 然后询问时提取每个符合题意列矩阵的答案项(不是列矩阵存了两项吗,一个 ...
- Codeforces 671C - Ultimate Weirdness of an Array(线段树维护+找性质)
Codeforces 题目传送门 & 洛谷题目传送门 *2800 的 DS,不过还是被我自己想出来了 u1s1 这个 D1C 比某些 D1D 不知道难到什么地方去了 首先碰到这类问题我们肯定考 ...
- 2019年CCPC网络赛 HDU 6703 array【权值线段树】
题目大意:给出一个n个元素的数组A,A中所有元素都是不重复的[1,n].有两种操作:1.将pos位置的元素+1e72.查询不属于[1,r]中的最小的>=k的值.强制在线. 题解因为数组中的值唯一 ...
- 【Codeforces718C】Sasha and Array 线段树 + 矩阵乘法
C. Sasha and Array time limit per test:5 seconds memory limit per test:256 megabytes input:standard ...
随机推荐
- Vue 入门之 Vuex 实战
Vue 入门之 Vuex 实战 引言 Vue 组件化做的确实非常彻底,它独有的 vue 单文件组件也是做的非常有特色.组件化的同时带来的是:组件之间的数据共享和通信的难题. 尤其 Vue 组件设计的就 ...
- spring-boot随笔
配置了spring-boot-starter-web的依赖后,会自动添加tomcat和spring mvc的依赖,那么spring boot 会对tomcat和spring mvc进行自动配置 < ...
- JS开发之CommonJs和AMD/CMD规范
CommonJS是主要为了JS在后端的表现制定的,他是不适合前端的,AMD(异步模块定义)出现了,它就主要为前端JS的表现制定规范. 在兼容CommonJS的系统中,你可以使用JavaScript开发 ...
- 【bzoj5118】Fib数列2 费马小定理+矩阵乘法
题目描述 Fib定义为Fib(0)=0,Fib(1)=1,对于n≥2,Fib(n)=Fib(n-1)+Fib(n-2) 现给出N,求Fib(2^n). 输入 本题有多组数据.第一行一个整数T,表示数据 ...
- salt-api安装以及简单实使用
1.安装说明 操作系统版本:CentOS Linux release 7.5.1804 (Core) saltstack版本:2018.3.2 已经关闭selinux.firewalld服务. 2.配 ...
- 年度编程语言最佳候选人:Kotlin vs. C
转瞬之间,今年已进入为期不足一个月的倒计时模式.在编程语言界,谁将问鼎 2017 年度编程语言?诸多开发者众说纷纭,有人说是最近风头正盛且被纳入中国高考科目的 Python.有人认为还是老牌常青藤 J ...
- 20个令人惊叹的深度学习应用(Demo+Paper+Code)
20个令人惊叹的深度学习应用(Demo+Paper+Code) 从计算机视觉到自然语言处理,在过去的几年里,深度学习技术被应用到了数以百计的实际问题中.诸多案例也已经证明,深度学习能让工作比之前做得更 ...
- CentOS服务器配置SSH免密码登录
由于工作需要,经常要登录到多台服务器远程操作,每次都是ssh user@host:port 再输入密码,时间长了,难免觉得乏味-- 故而从度娘那里扒来了一些让SSH免密码登录的办法,其实这也是使用Gi ...
- 【转】C/C++位域结构深入解析
C/C++位域结构深入解析 内存是以字节为单位进行编址的,编程语言的基本类型中,最小类型的长度一般也就是1个字节.然而,在解决某些问题时,必须要有二进制层面的表达手段(见本博客的自己动手实现DNS协议 ...
- hdu5449 Robot Dog (树形dp+倍增lca)
(警告:本篇博客包含大量人类本质内容) 先处理出来lca,然后就只需要知道从每个点到他的父亲.和从他的父亲到这个点的期望时间就可以了 我们设f[x]为x到他父亲的期望时间:g[x]为从x的父亲到x的期 ...