Description

你的面前有N个数排成一行。分别为A1, A2, … , An。你打算在每相邻的两个 Ai和 Ai+1 间都插入一个加号或者
减号或者乘号。那么一共有 3^(n-1) 种可能的表达式。你对所有可能的表达式的值的和非常感兴趣。但这毕竟太
简单了,所以你还打算支持一个修改操作,可以修改某个Ai 的值。你能够编写一个程序对每个修改都输出修改完
之后所有可能表达式的和吗?注意,修改是永久的,也就是说每次修改都是在上一次修改的基础上进行, 而不是
在最初的表达式上进行。

Input

第一行包含 2 个正整数 N 和 Q,为数的个数和询问的个数。
接下来一行 n 个非负整数,依次表示a1,a2...an
在接下来 Q 行,其中第 ?? 行两个非负整数Ti 和Vi,表示要将 Ati 修改为 Vi。其中 1 ≤ Ti ≤ N。
保证对于 1 ≤ J ≤ N, 1 ≤ i≤ Q,都有 Aj,Vi ≤ 10^4。
N,Q<=100000,本题仅有三组数据

Output

输出共 Q 行,其中第 i 行表示第 i 个询问之后所有可能表达式的和,对10^9 + 7 取模。

有贡献的一定是从序列的头开始连续一段的乘积.
因为如果有 $+$ 或 $-$ 的话一定能被另一种符号抵消掉.
那么,对于 $1$~$l$ 来说,贡献是 $2\times 3^{n-l-1}\times \prod_{i=1}^{l}A_{i}$
因为 $l$ 后面的符号肯定是 $+$ 或 $-$ ,而 $l+1$ 后面的符号就随便选了.
直接用线段树维护这个就行.
即 $\sum_{l=1}^{n}2\times 3^{n-l-1}\times\prod_{i=1}^{l}A_{i}$.
细节什么的就注意一下.

#include <bits/stdc++.h>
using namespace std;
namespace IO {
void setIO(string s) {
string in=s+".in";
freopen(in.c_str(),"r",stdin);
}
};
typedef long long ll;
const int maxn=100004;
const ll mod=1000000007;
int n,m;
ll A[maxn],mul[maxn*4],Ans[maxn*4],qpow[maxn];
void pushup(int x) {
mul[x]=mul[x<<1]*mul[(x<<1)|1]%mod;
Ans[x]=(Ans[x<<1]+mul[x<<1]*Ans[(x<<1)|1]%mod)%mod;
}
void build(int l,int r,int now) {
if(l==r) {
mul[now]=A[l];
if(l==n) Ans[now]=A[l];
else Ans[now]=A[l]*1ll*2*qpow[n-l-1]%mod;
return;
}
int mid=(l+r)>>1;
build(l,mid,now<<1);
build(mid+1,r,(now<<1)|1);
pushup(now);
}
void update(int l,int r,int now,int p,int v) {
if(l==r) {
A[l]=1ll*v;
mul[now]=A[l];
if(l==n) Ans[now]=A[l];
else Ans[now]=A[l]*1ll*2*qpow[n-l-1]%mod;
return;
}
int mid=(l+r)>>1;
if(p<=mid) update(l,mid,now<<1,p,v);
else update(mid+1,r,(now<<1)|1,p,v);
pushup(now);
}
int main() {
using namespace IO;
// setIO("input");
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i) scanf("%lld",&A[i]);
qpow[0]=mul[0]=Ans[0]=1;
for(int i=1;i<=n+2;++i) qpow[i]=qpow[i-1]*3%mod;
build(1,n,1);
for(int cas=1;cas<=m;++cas) {
int t,v;
scanf("%d%d",&t,&v);
update(1,n,1,t,v);
printf("%lld\n",Ans[1]%mod);
}
return 0;
}

  

BZOJ 4597: [Shoi2016]随机序列 线段树 + 思维的更多相关文章

  1. BZOJ 4597: [Shoi2016]随机序列

    4597: [Shoi2016]随机序列 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 255  Solved: 174[Submit][Status ...

  2. 【BZOJ4597】[Shoi2016]随机序列 线段树

    [BZOJ4597][Shoi2016]随机序列 Description 你的面前有N个数排成一行.分别为A1, A2, … , An.你打算在每相邻的两个 Ai和 Ai+1 间都插入一个加号或者减号 ...

  3. Bzoj 2752 高速公路 (期望,线段树)

    Bzoj 2752 高速公路 (期望,线段树) 题目链接 这道题显然求边,因为题目是一条链,所以直接采用把边编上号.看成序列即可 \(1\)与\(2\)号点的边连得是. 编号为\(1\)的点.查询的时 ...

  4. BZOJ 4552(二分+线段树+思维)

    题面 传送门 分析 此题是道好题! 首先要跳出思维定势,不是去想如何用数据结构去直接维护排序过程,而是尝试二分a[p]的值 设二分a[p]的值为x 我们将大于x的数标记为1,小于等于x的数标记为0 则 ...

  5. 【插队问题-线段树-思维巧妙】【poj2828】Buy Tickets

    可耻的看了题解 巧妙的思维 逆序插入,pos 代表的意义为前面要有pos个空格才OK: 证明:仔细思考一下就觉得是正确的,但是要想到这种方式还是要很聪明,空格是前面的几个数字所形成的,所以要特地留出来 ...

  6. BZOJ.3938.Robot(李超线段树)

    BZOJ UOJ 以时间\(t\)为横坐标,位置\(p\)为纵坐标建坐标系,那每个机器人就是一条\(0\sim INF\)的折线. 用李超线段树维护最大最小值.对于折线分成若干条线段依次插入即可. 最 ...

  7. BZOJ.1558.[JSOI2009]等差数列(线段树 差分)

    BZOJ 洛谷 首先可以把原序列\(A_i\)转化成差分序列\(B_i\)去做. 这样对于区间加一个等差数列\((l,r,a_0,d)\),就可以转化为\(B_{l-1}\)+=\(a_0\),\(B ...

  8. BZOJ 3779: 重组病毒(线段树+lct+树剖)

    题面 escription 黑客们通过对已有的病毒反编译,将许多不同的病毒重组,并重新编译出了新型的重组病毒.这种病毒的繁殖和变异能力极强.为了阻止这种病毒传播,某安全机构策划了一次实验,来研究这种病 ...

  9. BZOJ 3123 森林(函数式线段树)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=3123 题意: 思路:总的来说,查询区间第K小利用函数式线段树的减法操作.对于两棵树的合并 ...

随机推荐

  1. 【机器学习】聚类算法:层次聚类、K-means聚类

    聚类算法实践(一)--层次聚类.K-means聚类 摘要: 所谓聚类,就是将相似的事物聚集在一 起,而将不相似的事物划分到不同的类别的过程,是数据分析之中十分重要的一种手段.比如古典生物学之中,人们通 ...

  2. 四、Kubernetes_V1.10集群部署-master-创建kubeconfig

    1.生成配置文件 # 创建 TLS Bootstrapping Token # export BOOTSTRAP_TOKEN=$( /dev/urandom | od -An -t x | tr -d ...

  3. 解决 Illegal DefaultValue null for parameter type integer 异常

    该异常是由 swagger 引起的 swagger 版本 1.9.2 解决原因:重新导入 swagger-annotations 和 swagger-models 版本 为 1.5.21 pom.xm ...

  4. spring + redis 实例(一)

    这一篇主要是redis操作工具类以及基本配置文本储存 首先我们需要定义一个redisUtil去操作底层redis数据库: package com.lcc.cache.redis; import jav ...

  5. [题解][SHOI2013]超级跳马 动态规划/递推式/矩阵快速幂优化

    这道题... 让我见识了纪中的强大 这道题是来纪中第二天(7.2)做的,这么晚写题解是因为 我去学矩阵乘法啦啦啦啦啦对矩阵乘法一窍不通的童鞋戳链接啦 层层递推会TLE,正解矩阵快速幂 首先题意就是给你 ...

  6. MacOS 下文件读取问题

    使用Xcode编写C++程序可以直接使用fstream读写文件,代码如下: const char* path1 = [path UTF8String];string filename = path1; ...

  7. $Prufer$序列

    \(Prufer\)序列 \(Prufer\)序列与树的相互转换: 树->\(Prufer\)序列 找到一个编号最小的叶子结点,把这个点删掉并且把跟他连着的那个点的编号加入\(Prufer\)序 ...

  8. python-day16(正式学习)

    目录 模块 什么是模块? 模块的四种形式 为什么要用模块 如何用模块 import from...import... 异同 循环导入问题 解决方案 1. 2. 模块搜索路径 random模块 模块 什 ...

  9. 【统计】Causal Inference

    [统计]Causal Inference 原文传送门 http://www.stat.cmu.edu/~larry/=sml/Causation.pdf 过程 一.Prediction 和 causa ...

  10. Java Script 基本知识点

                          JavaScript是一种基于对象和事件驱动的脚本语言,它提供了一些专有的类.对象及函数 1.基本数据类型 JavaScript提供了4种基本的数据类型用来 ...