【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 并查集的更多相关文章

  1. CF 878E Numbers on the blackboard 并查集 离线 贪心

    LINK:Numbers on the blackboard 看完题觉得很难. 想了一会发现有点水 又想了一下发现有点困难. 最终想到了 但是实现的时候 也很难. 先观察题目中的这个形式 使得前后两个 ...

  2. Codeforces 878 E. Numbers on the blackboard

    Codeforces 878 E. Numbers on the blackboard 解题思路 有一种最优策略是每次选择最后面一个大于等于 \(0\) 的元素进行合并,这样做完以后相当于给这个元素乘 ...

  3. POJ2985 The k-th Largest Group[树状数组求第k大值+并查集||treap+并查集]

    The k-th Largest Group Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 8807   Accepted ...

  4. POJ1703Find them, Catch them[种类并查集]

    Find them, Catch them Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 42416   Accepted: ...

  5. POJ 1703 Find them, Catch them(带权并查集)

    传送门 Find them, Catch them Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 42463   Accep ...

  6. *HDU1829 并查集

    A Bug's Life Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tot ...

  7. [并查集] POJ 1703 Find them, Catch them

    Find them, Catch them Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 43132   Accepted: ...

  8. poj1417 带权并查集 + 背包 + 记录路径

    True Liars Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 2713   Accepted: 868 Descrip ...

  9. poj1984 带权并查集(向量处理)

    Navigation Nightmare Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 5939   Accepted: 2 ...

随机推荐

  1. Linux下php安装Redis安装

    1. 下载  redis-2.4.14.tar.gz 2. 解压 tar -zxvf redis-2.4.14.tar.gz 3.cd redis-2.4.14 4. make 注意:出错 1. CC ...

  2. yum常用操作

    一.yum安装使用: 1.Yum:rpm的前端程序,用来解决软件包相关依赖性,可以在多个库之间定位软件包,up2date的替代工具 2.yum repository:yum repo,存储了众多rpm ...

  3. create table repo_folder_operate_log_bak as select * from repo_folder_operate_log;

    create table repo_folder_operate_log_bak as select * from repo_folder_operate_log;

  4. 标准代码页(codepage)列表

    https://blog.csdn.net/jianggujin/article/details/80325461 这篇文章有待完善 代码页 简称 全称 37 IBM037 IBM EBCDIC (U ...

  5. it码农之心灵鸡汤(一)

    到底该怎么面对工作,到底怎么面临人生.到底怎么面临青春,对于打工的人来说这些一直都是心中一直无法解惑的谜团. 对于人们怎样看待工作,以前华为创始人任正非说过:非常多人问我,来公司工作有没有双休?需不须 ...

  6. C#------Aspose的License文件

    Aspose官网: https://docs.aspose.com/display/cellsnet/Home 下载地址: http://vdisk.weibo.com/s/uoya0tRiZNf0X ...

  7. 03-Linux各目录及每个目录的详细介绍

    Linux各目录及每个目录的详细介绍 [常见目录说明] 目录 /bin 存放二进制可执行文件(ls,cat,mkdir等),常用命令一般都在这里. /etc 存放系统管理和配置文件 /home 存放所 ...

  8. SpringMVC -- 梗概--源码--贰--静态资源的访问问题

    配置:<mvc:default-servlet-handler/> 1>静态资源:除了Servlet.Controller之外的资源,如:js,css,png,html等 2> ...

  9. Yarn执行流程

    在Yarn中,JobTracker被分为两部分:ResourceManager(RM)和ApplicationMaster(AM). MRv1主要由三部分组成:编程模型(API).数据处理引擎(Map ...

  10. 在SELECT DISTINCT 状况下使用 Order BY Newid() 随机数选出记录

    在日常作业中,有时候可能是一些活动要抽出得奖人或选出抽查的一些名单, 就常常会使用到 Order BY Newid() 的方式来做随机数选出, 但有可能的状况需是要搭配到 DISTINCT 来选出,这 ...