【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. 【WP8】关于类库本地化问题

    WPToolkit中的ToggleSwitch开关控件是比较常用的控件,之前在做的的时候遇到一个问题,默认语言改为中文,手机系统语言也为中文,但是开关状态无法应用本地化的语言库,开关状态总是显示On/ ...

  2. jquery绑定事件的坑,重复绑定问题

    我实现点击table表格中的删除按钮,找到当前按钮的祖先元素tr 然后删除该行,但是我首先点击删除的时候要先弹出提示框,是否要下载,这时在点击删除按钮删除,之前没有考虑到事件重复绑定问题,所以每次点击 ...

  3. jenkins 升级jdk到1.8.0 报java.io.IOException:Unable to read /var/lib/jenkins/config.xml

    今天手动下载安装了jdk1.8.0, 并修改了配置文件,当前默认使用该版本的jdk.但是报出一下错误: 问题查到: https://issues.jenkins-ci.org/browse/JENKI ...

  4. 用Fiddler查看 Android/iOS 网络请求

    1.下载fiddler,尽量到官方网站找最新的版本 我这里也放了一个:http://files.cnblogs.com/xiaokang088/fiddler4setup.zip 2. 打开Fiddl ...

  5. 怎么让BarTender对象等间距分布

    在BarTender 2016设计条码标签时,我们需要让对象分布尽可能整齐美观,例如实现对象的对齐,对象等间距分布等.这些在作为世界上最好且最受信任的条码打印软件BarTender中,都是可以很轻松的 ...

  6. PHP的五大阶段

    PHP程序员必须懂前端,后端,数据库,服务器.具体的学习顺序是: 第一阶段:扫盲.了解什么是B/S模式,原理上知道从浏览器输入一个url是如何获取到信息的流程.熟悉html,能快速地用div+css写 ...

  7. MySQL数据库辅助类

    /** *创建人:CalvinR *说明:数据库辅助类 **/ namespace Study.Utilities.MySql_Connect { /// <summary> /// My ...

  8. 01-虚拟软件vmware安装

    什么是虚拟软件: 虚拟原件是一个可以使你在一台机器上同时运行二个或更多Windows.LINUX等系统.它可以模拟一个标准PC环境.这个环境和真实的计算机一样,都有芯片组.CPU.内存.显卡.声卡.网 ...

  9. Linux CentOS6.5上搭建环境遇到的问题

    1.卸载CentOS自带的JDK 查看centos上 安装的jdk:rpm -qa|grep jdk 出现如下: java-1.7.0-openjdk-1.7.0.45-2.4.3.3.el6.x86 ...

  10. hydra 及相关示例

    http://www.cnblogs.com/mchina/archive/2013/01/01/2840815.html https://www.thc.org/thc-hydra/ 语法 # hy ...