题目链接:

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

  1. Light oj-1100 - Again Array Queries,又是这个题,上次那个题用的线段树,这题差点就陷坑里了,简单的抽屉原理加暴力就可以了,真是坑~~

                                                                              1100 - Again Array Queries ...

  2. HDU - 4366 Successor DFS序 + 分块暴力 or 线段树维护

    给定一颗树,每个节点都有忠诚和能力两个参数,随意指定一个节点,要求在它的子树中找一个节点代替它,这个节点要满足能力值大于它,而且是忠诚度最高的那个. 首先,dfs一下,处理出L[i], R[i]表示d ...

  3. CF719E. Sasha and Array [线段树维护矩阵]

    CF719E. Sasha and Array 题意: 对长度为 n 的数列进行 m 次操作, 操作为: a[l..r] 每一项都加一个常数 C, 其中 0 ≤ C ≤ 10^9 求 F[a[l]]+ ...

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

  5. 线段树维护矩阵【CF718C】 Sasha and Array

    Description 有一个长为\(n\)的数列\(a_{1},a_{2}...a_{n}\),你需要对这个数列维护如下两种操作: \(1\space l \space r\space x\) 表示 ...

  6. CF718C Sasha and Array(线段树维护矩阵)

    题解 (不会矩阵加速的先去学矩阵加速) 反正我想不到线段树维护矩阵.我太菜了. 我们在线段树上维护一个区间的斐波那契的列矩阵的和. 然后询问时提取每个符合题意列矩阵的答案项(不是列矩阵存了两项吗,一个 ...

  7. Codeforces 671C - Ultimate Weirdness of an Array(线段树维护+找性质)

    Codeforces 题目传送门 & 洛谷题目传送门 *2800 的 DS,不过还是被我自己想出来了 u1s1 这个 D1C 比某些 D1D 不知道难到什么地方去了 首先碰到这类问题我们肯定考 ...

  8. 2019年CCPC网络赛 HDU 6703 array【权值线段树】

    题目大意:给出一个n个元素的数组A,A中所有元素都是不重复的[1,n].有两种操作:1.将pos位置的元素+1e72.查询不属于[1,r]中的最小的>=k的值.强制在线. 题解因为数组中的值唯一 ...

  9. 【Codeforces718C】Sasha and Array 线段树 + 矩阵乘法

    C. Sasha and Array time limit per test:5 seconds memory limit per test:256 megabytes input:standard ...

随机推荐

  1. wordpress学习三:wordpress自带的模板学习

    在<学习二>里,大概说了下怎么去查找模板,本节我们以一个简单的模板为例子,继续说说wordpress的模板机制,看看做一个自己的模板需要哪些知识点. 页面模板渲染 wordpress的模板 ...

  2. Java单元测试框架 JUnit

    Java单元测试框架 JUnit JUnit是一个Java语言的单元测试框架.它由Kent Beck和Erich Gamma建立,逐渐成为源于KentBeck的sUnit的xUnit家族中为最成功的一 ...

  3. Linux命令(十) 在文件或目录之间创建链接 ln

    命令简介 ln 命令用于连接文件或目录,如同时指定两个以上的文件或目录,且最后的目的地是一个已经存在的目录,则会把前面指定的所有文件或目录复制到该目录中.若同时指定多个文件或目录,且最后的目的地是一个 ...

  4. Spring之事务操作(配置文件)

    UserDao.java package helloworld.tx; import org.springframework.jdbc.core.JdbcTemplate; public class ...

  5. 用jq获取元素内文本,但不包括其子元素内的文本值的方法

    <li id="listItem"> This is some text <span id="firstSpan">First span ...

  6. oracle 每个类别取几条的语法怎么写

    select *from (select t.*,row_number() over(partition by t.公司名 order by 1) rn  from t)where rn<=10

  7. 【题解】 [HNOI2015]菜肴制作 (拓扑排序)

    题目描述 知名美食家小 A被邀请至ATM 大酒店,为其品评菜肴. ATM 酒店为小 A 准备了 N 道菜肴,酒店按照为菜肴预估的质量从高到低给予1到N的顺序编号,预估质量最高的菜肴编号为1. 由于菜肴 ...

  8. 洛谷 P2765 魔术球问题 解题报告

    P2765 魔术球问题 题目描述 问题描述: 假设有\(n\)根柱子,现要按下述规则在这\(n\)根柱子中依次放入编号为\(1,2,3,\dots\)的球. \((1)\) 每次只能在某根柱子的最上面 ...

  9. C++代理模式

    主要根据代理模式整理,感谢作者分享! [DP]上的定义:为其他对象提供一种代理以控制对这个对象的访问.有四种常用的情况:(1)远程代理,(2)虚代理,(3)保护代理,(4)智能引用.本文主要介绍虚代理 ...

  10. 深入理解JS this,作用域

    深入理解JS this 阮一峰博客链接http://www.ruanyifeng.com/blog/2010/04/using_this_keyword_in_javascript.html this ...