【CF878E】Numbers on the blackboard 并查集
【CF878E】Numbers on the blackboard
题意:给你一个长度为n个数列,你每次可以进行如下操作:
选取两个相邻的数x,y(x在y左面),然后将这两个数去掉,用x+2y替换它。
重复此操作直到序列中只有一个数为止。你可以任意决定每次合并哪两个数,求最后得到的数的最大值。
为了加大难度,现有q次询问,每次询问给出l,r,问你对[l,r]这段区间进行操作能得到的最大值是什么。
n,q<=100000,ai<=10^9
题解:先不考虑l,r的限制,整个操作可以看成:让你最大化$\sum a_i\times 2^{k_i},k_0=0,1<=k_i<=k_{i-1}+1$。我们从左往右逐个加入每个数,如果ai是负数,我们直接令$k_i=1$;否则我们令$k_i=k_{i-1}+1$。这样的话最终得到的k一定是分为若干段,每段(除了第一段)都是开头的k=1,然后k不断++。我们还需要判断:在加入ai后,如果最后一段合并之后的和变成了正数,那么还要将最后一段整体向前合并,直到和为负数为止。
如果考虑l,r呢?我们可以离线,对于r=i,我们用并查集找到l所在的块,然后统计一下答案即可。
在判断一个块内合并后总和是否是正数时要讨论一下。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <utility>
using namespace std;
#define mp(A,B) make_pair(A,B)
typedef long long ll;
const ll P=1000000007;
const ll inv=500000004;
const int maxn=100010;
int n,m;
int f[maxn],pre[maxn];
ll v[maxn],s[maxn],sum[maxn],ans[maxn],pw[maxn],sp[maxn];
vector<pair<int,int> > q[maxn];
vector<pair<int,int> >::iterator it;
int find(int x)
{
return (f[x]==x)?x:(f[x]=find(f[x]));
}
inline void merge(int a,int b)
{
if((a-pre[a]>31&&sum[b]>0)||sum[a]+(sum[b]<<(a-pre[a]))>P) sum[b]=P;
else sum[b]=sum[a]+(sum[b]<<(a-pre[a]));
f[a]=f[b],pre[b]=pre[a];
}
inline ll query(int a,int b)
{
return (s[a]-s[b+1]*pw[b-a+1]%P+P)%P;
}
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+(gc^'0'),gc=getchar();
return ret*f;
}
int main()
{
n=rd(),m=rd();
int i,a,b;
for(pw[0]=i=1;i<=n;i++) f[i]=i,pre[i]=i-1,v[i]=rd(),pw[i]=(pw[i-1]<<1)%P;
for(i=n;i>=1;i--) s[i]=((s[i+1]<<1)+v[i]+P)%P;
for(i=1;i<=m;i++) a=rd(),b=rd(),q[b].push_back(mp(a,i));
for(i=1;i<=n;i++)
{
sum[i]=v[i];
while(pre[i]&&sum[i]>=0) merge(pre[i],i);
sp[i]=(sp[pre[i]]+(query(pre[i]+1,i)<<1))%P;
for(it=q[i].begin();it!=q[i].end();it++)
{
a=(*it).first,b=find(a);
ans[(*it).second]=(sp[i]-sp[b]+query(a,b)+P)%P;
}
}
for(i=1;i<=m;i++) printf("%I64d\n",ans[i]);
return 0;
}
【CF878E】Numbers on the blackboard 并查集的更多相关文章
- CF 878E Numbers on the blackboard 并查集 离线 贪心
LINK:Numbers on the blackboard 看完题觉得很难. 想了一会发现有点水 又想了一下发现有点困难. 最终想到了 但是实现的时候 也很难. 先观察题目中的这个形式 使得前后两个 ...
- Codeforces 878 E. Numbers on the blackboard
Codeforces 878 E. Numbers on the blackboard 解题思路 有一种最优策略是每次选择最后面一个大于等于 \(0\) 的元素进行合并,这样做完以后相当于给这个元素乘 ...
- POJ2985 The k-th Largest Group[树状数组求第k大值+并查集||treap+并查集]
The k-th Largest Group Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 8807 Accepted ...
- POJ1703Find them, Catch them[种类并查集]
Find them, Catch them Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 42416 Accepted: ...
- POJ 1703 Find them, Catch them(带权并查集)
传送门 Find them, Catch them Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 42463 Accep ...
- *HDU1829 并查集
A Bug's Life Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...
- [并查集] POJ 1703 Find them, Catch them
Find them, Catch them Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 43132 Accepted: ...
- poj1417 带权并查集 + 背包 + 记录路径
True Liars Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 2713 Accepted: 868 Descrip ...
- poj1984 带权并查集(向量处理)
Navigation Nightmare Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 5939 Accepted: 2 ...
随机推荐
- Oracle 高级查询
Oracle SQL 一些函数用法 以下sql环境都是在 Oracle 11g/scott完成 Group by 与GROUP BY一起使用的关建字 GROUPING,GROUP SET,ROLLUP ...
- [转]java的(PO,VO,TO,BO,DAO,POJO)类名包名解释
java的(PO,VO,TO,BO,DAO,POJO)类名包名解释 2015-04-28 20:11 by Loull, 18 阅读, 0 评论, 收藏, 编辑 VO:值对象.视图对象 PO:持久对象 ...
- easyui分页,编辑datagrid某条数据保存以后跳转到某一页
参考资料:http://caizhilin2010.iteye.com/blog/1731698 问题:商品列表页面采用easyui的datagrid展示数据,编辑某行数据保存以后,要求跳转到 用户在 ...
- SQL语句:一个表,通过一个字段查找另外一个字段不相同值
select * from [dbo].[Sys_MemberKey] a where exists(select * from [Sys_MemberKey] b where a.FMachineC ...
- linux将标准输出和标准错误输出都重定向到一个文件?
需求描述: 今天在写crontab,里面有标准输出和错误输出,之前使用的是 > /dev/null 2>&1 那这个意思也就等同于将标准输出和错误输出都输出到/dev/null中, ...
- 06-Linux RPM 命令参数使用详解
rpm 执行安装包二进制包(Binary)以及源代码包(Source)两种.二进制包可以直接安装在计算机中,而源代码包将会由 RPM自动编译.安装.源代码包经常以src.rpm作为后缀名. 常用命令组 ...
- scala try monad
当输入的数据格式不正确时,ActivityData 中会出现 OutofIndex 错误,但更多的时候我们只关心想要的结果而不想了解出现了怎样的错误,然后会写出这样的代码 def parseCSV ...
- 找不同diff-打补丁patch
Q:为什么要找不同,为什么要打补丁? A: 在Linux应用中,作为DBA,我们知道MySQL跑在Linux系统之上,数据库最重要的追求就是性能,“稳”是重中之重,所以不能动不动就是换系统或是换这换那 ...
- java.util.concurrent.RejectedExecutionException 线程池饱和
java.util.concurrent.RejectedExecutionException at java.util.concurrent.ThreadPoolExecutor$AbortPoli ...
- Kafka consumer group位移重设
本文阐述如何使用Kafka自带的kafka-consumer-groups.sh脚本随意设置消费者组(consumer group)的位移.需要特别强调的是, 这是0.11.0.0版本提供的新功能且只 ...