$n \leq 100000$的数列,数字范围$-1e9,1e9$,现$q \leq 1e5$个每次问在一个区间玩游戏,能得到的最大的数。“游戏”:选相邻两个数$a_x,a_y$,然后把他们删掉,变成$a_x+2a_y$,直到序列中只剩一个数。答案$\mod \ \ 1e9+7$。

单次询问可用贪心解决:首先第一个数系数一定是1,后面的数的系数是$2^k,k\geq 1$且$k$不会比上一个数的$k$多2以上。用一块表示给某个区间分配了系数2,4,8,16,。。。,也就是这个区间从左到右一个个合并,那么在数列右边加入一个新的数时,如果这个数是负数,那给他新开一块,否则合并到上一块中,若上一块的答案因此变成了正的,那就继续往前合并。

多次询问只需离线一下,记一下每个块的位置,然后按上面的方法模拟,询问时二分一下就好了。不过要注意,询问时可能左端点处不是一个完整块,这时需要把那个块的后缀单独拿出来算答案。

有个大问题:数字很大,如何判断大小以决定某个块是否要往前并?可以发现负权值最小只到2e9,因此超过2e9的正权值记成2e9+1就行了。

 //#include<iostream>
#include<cstring>
#include<cstdio>
//#include<math.h>
//#include<set>
//#include<queue>
//#include<vector>
#include<algorithm>
#include<stdlib.h>
using namespace std; #define LL long long
int qread()
{
char c; int s=,f=; while ((c=getchar())<'' || c>'') (c=='-') && (f=-);
do s=s*+c-''; while ((c=getchar())>='' && c<=''); return s*f;
} //Pay attention to '-' , LL and double of qread!!!! int n,m;
#define maxn 100011
const int mod=1e9+; int a[maxn],pos[maxn],bin[maxn],inv[maxn],sum[maxn],lp=,val[maxn],vv[maxn],svv[maxn];
struct Ques{int l,r,id; bool operator < (const Ques &b) const {return r<b.r;} }q[maxn];
int ans[maxn]; int WWW(LL v) {return v>?:v;} int main()
{
n=qread(); m=qread();
bin[]=inv[]=; for (int i=;i<=n;i++)
a[i]=qread(),bin[i]=(bin[i-]<<)%mod,inv[i]=1ll*inv[i-]*((mod+)>>)%mod,
sum[i]=((sum[i-]+1ll*a[i]*bin[i])%mod+mod)%mod;
for (int i=;i<=m;i++) {q[i].l=qread(); q[q[i].id=i].r=qread();}
sort(q+,q++m); pos[lp=]=; int j=; val[]=a[]*; vv[]=svv[]=((a[]*)%mod+mod)%mod;
while (j<=m && q[j].r==) ans[q[j].id]=(a[]+mod)%mod,j++;
for (int i=;i<=n;i++)
{
if (a[i]<=) pos[++lp]=i,val[lp]=*a[i],vv[lp]=(a[i]*2ll%mod+mod)%mod,svv[lp]=(svv[lp-]+vv[lp])%mod;
else
{
int cur=WWW(0ll+val[lp]+bin[pos[lp]-pos[lp-]+]*1ll*a[i]);
int cvv=(vv[lp]+bin[pos[lp]-pos[lp-]+]*1ll*a[i])%mod; lp--;
while (lp && cur>)
{
cur=WWW(0ll+val[lp]+(pos[lp]-pos[lp-]>?:bin[pos[lp]-pos[lp-]])*1ll*cur);
cvv=(vv[lp]+bin[pos[lp]-pos[lp-]]*1ll*cvv)%mod; lp--;
}
val[++lp]=cur; pos[lp]=i; vv[lp]=cvv; svv[lp]=(svv[lp-]+vv[lp])%mod;
}
while (j<=m && q[j].r==i)
{
if (q[j].l==q[j].r) {ans[q[j].id]=(a[i]+mod)%mod; j++; continue;}
int l=q[j].l+,Ans=(a[q[j].l]+mod)%mod;
int L=,R=lp;
while (L<R)
{
int mid=(L+R)>>;
if (pos[mid]>=l) R=mid; else L=mid+;
}
Ans=(Ans+svv[lp]-svv[L])%mod; Ans=(Ans+mod)%mod;
Ans=(Ans+(sum[pos[L]]-sum[l-]+mod)*1ll*inv[l-])%mod;
ans[q[j].id]=Ans;
j++;
}
} for (int i=;i<=m;i++) printf("%d\n",ans[i]);
return ;
}

Codeforces878E. Numbers on the blackboard的更多相关文章

  1. 【CF878E】Numbers on the blackboard 并查集

    [CF878E]Numbers on the blackboard 题意:给你一个长度为n个数列,你每次可以进行如下操作: 选取两个相邻的数x,y(x在y左面),然后将这两个数去掉,用x+2y替换它. ...

  2. Codeforces 878 E. Numbers on the blackboard

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

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

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

  4. Codeforces Beta Round #51 B. Smallest number dfs

    B. Smallest number Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/55/pro ...

  5. ZOJ 3529 A Game Between Alice and Bob(博弈论-sg函数)

    ZOJ 3529 - A Game Between Alice and Bob Time Limit:5000MS     Memory Limit:262144KB     64bit IO For ...

  6. ZOJ 3529 A Game Between Alice and Bob 博弈好题

    A Game Between Alice and Bob Time Limit: 5 Seconds      Memory Limit: 262144 KB Alice and Bob play t ...

  7. ural1682 Crazy Professor

    Crazy Professor Time limit: 1.0 secondMemory limit: 64 MB Professor Nathan Mathan is crazy about mat ...

  8. [HDU - 5170GTY's math problem 数的精度类

    题目链接:HDU - 5170GTY's math problem 题目描述 Description GTY is a GodBull who will get an Au in NOI . To h ...

  9. BestCoder Round #29——A--GTY's math problem(快速幂(对数法))、B--GTY's birthday gift(矩阵快速幂)

    GTY's math problem Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Other ...

随机推荐

  1. javaweb基础(24)_jsp一般的标签开发

    一.标签技术的API 1.1.标签技术的API类继承关系 二.标签API简单介绍 2.1.JspTag接口 JspTag接口是所有自定义标签的父接口,它是JSP2.0中新定义的一个标记接口,没有任何属 ...

  2. C语言单链表的实现

    // //  main.c //  gfhjhgdf // //  Created by chenhao on 13-12-23. //  Copyright (c) 2013年 chenhao. A ...

  3. python入门:输出1-10以内除去7的所有数(自写)

    #!/usr/bin/env python # -*- coding:utf-8 -*- #输出1-10以内除去7的所有数(自写) """ 变量kaishi赋值等于1,w ...

  4. CSS清除浮动8大方法

    CSS清除浮动是每一位web前端工程师都要掌握的技术,也是让每一位刚入门的前端工程师感到头疼的问题, 下面就来讲一下CSS清除浮动的原理和各种解决方法,大家可以根据实际情况选择最佳的解决方案. 在用D ...

  5. PHP CURL错误: error:140943FC

    使用PHP访问https网站的时候,间歇性会报error:140943FC错误.google之,通过如下方案可处理: 1.服务器ssl版本较高 curl_setopt($this->curl, ...

  6. python基础-面向对象的三大特征

    继承 单继承 父类 基类 子类 派生类 继承:是面向对象软件技术当中的一个概念,如果一个类别A“继承自”另一个类别B,就把这个A称为“B的子类别”,而把B称为“A的父类别”也可以称“B是A的超类”. ...

  7. Python中的属性访问与描述符

    Python中的属性访问与描述符 请给作者点赞--> 原文链接 在Python中,对于一个对象的属性访问,我们一般采用的是点(.)属性运算符进行操作.例如,有一个类实例对象foo,它有一个nam ...

  8. perl第三章 列表和数组

    访问数组中的元素    $fred[0]   $fred[1] $number=2.75; print $fred[$number-1]  结果就是print $fred[1] 特殊的数组索引1.对索 ...

  9. acmer之ubuntu下安装Eclipse

    ubuntu是acmer常用的系统,配置起CB还是比较简单的三行命令就OK了 //Current stable version of Code::Blocks IDE (16.01) //To ins ...

  10. queue 类

    一:普通队列 1.队列特征:先进先出,它只允许在一端(队尾)进行插入元素操作,在另一端(队头)进行删除元素操作 2. 存取类函数 front():用来取出queue中的队头元素,对应于front()函 ...