BZOJ 4597: [Shoi2016]随机序列 线段树 + 思维
Description
Input
Output
有贡献的一定是从序列的头开始连续一段的乘积.
因为如果有 $+$ 或 $-$ 的话一定能被另一种符号抵消掉.
那么,对于 $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]随机序列 线段树 + 思维的更多相关文章
- BZOJ 4597: [Shoi2016]随机序列
4597: [Shoi2016]随机序列 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 255 Solved: 174[Submit][Status ...
- 【BZOJ4597】[Shoi2016]随机序列 线段树
[BZOJ4597][Shoi2016]随机序列 Description 你的面前有N个数排成一行.分别为A1, A2, … , An.你打算在每相邻的两个 Ai和 Ai+1 间都插入一个加号或者减号 ...
- Bzoj 2752 高速公路 (期望,线段树)
Bzoj 2752 高速公路 (期望,线段树) 题目链接 这道题显然求边,因为题目是一条链,所以直接采用把边编上号.看成序列即可 \(1\)与\(2\)号点的边连得是. 编号为\(1\)的点.查询的时 ...
- BZOJ 4552(二分+线段树+思维)
题面 传送门 分析 此题是道好题! 首先要跳出思维定势,不是去想如何用数据结构去直接维护排序过程,而是尝试二分a[p]的值 设二分a[p]的值为x 我们将大于x的数标记为1,小于等于x的数标记为0 则 ...
- 【插队问题-线段树-思维巧妙】【poj2828】Buy Tickets
可耻的看了题解 巧妙的思维 逆序插入,pos 代表的意义为前面要有pos个空格才OK: 证明:仔细思考一下就觉得是正确的,但是要想到这种方式还是要很聪明,空格是前面的几个数字所形成的,所以要特地留出来 ...
- BZOJ.3938.Robot(李超线段树)
BZOJ UOJ 以时间\(t\)为横坐标,位置\(p\)为纵坐标建坐标系,那每个机器人就是一条\(0\sim INF\)的折线. 用李超线段树维护最大最小值.对于折线分成若干条线段依次插入即可. 最 ...
- BZOJ.1558.[JSOI2009]等差数列(线段树 差分)
BZOJ 洛谷 首先可以把原序列\(A_i\)转化成差分序列\(B_i\)去做. 这样对于区间加一个等差数列\((l,r,a_0,d)\),就可以转化为\(B_{l-1}\)+=\(a_0\),\(B ...
- BZOJ 3779: 重组病毒(线段树+lct+树剖)
题面 escription 黑客们通过对已有的病毒反编译,将许多不同的病毒重组,并重新编译出了新型的重组病毒.这种病毒的繁殖和变异能力极强.为了阻止这种病毒传播,某安全机构策划了一次实验,来研究这种病 ...
- BZOJ 3123 森林(函数式线段树)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=3123 题意: 思路:总的来说,查询区间第K小利用函数式线段树的减法操作.对于两棵树的合并 ...
随机推荐
- 【机器学习】聚类算法:层次聚类、K-means聚类
聚类算法实践(一)--层次聚类.K-means聚类 摘要: 所谓聚类,就是将相似的事物聚集在一 起,而将不相似的事物划分到不同的类别的过程,是数据分析之中十分重要的一种手段.比如古典生物学之中,人们通 ...
- 四、Kubernetes_V1.10集群部署-master-创建kubeconfig
1.生成配置文件 # 创建 TLS Bootstrapping Token # export BOOTSTRAP_TOKEN=$( /dev/urandom | od -An -t x | tr -d ...
- 解决 Illegal DefaultValue null for parameter type integer 异常
该异常是由 swagger 引起的 swagger 版本 1.9.2 解决原因:重新导入 swagger-annotations 和 swagger-models 版本 为 1.5.21 pom.xm ...
- spring + redis 实例(一)
这一篇主要是redis操作工具类以及基本配置文本储存 首先我们需要定义一个redisUtil去操作底层redis数据库: package com.lcc.cache.redis; import jav ...
- [题解][SHOI2013]超级跳马 动态规划/递推式/矩阵快速幂优化
这道题... 让我见识了纪中的强大 这道题是来纪中第二天(7.2)做的,这么晚写题解是因为 我去学矩阵乘法啦啦啦啦啦对矩阵乘法一窍不通的童鞋戳链接啦 层层递推会TLE,正解矩阵快速幂 首先题意就是给你 ...
- MacOS 下文件读取问题
使用Xcode编写C++程序可以直接使用fstream读写文件,代码如下: const char* path1 = [path UTF8String];string filename = path1; ...
- $Prufer$序列
\(Prufer\)序列 \(Prufer\)序列与树的相互转换: 树->\(Prufer\)序列 找到一个编号最小的叶子结点,把这个点删掉并且把跟他连着的那个点的编号加入\(Prufer\)序 ...
- python-day16(正式学习)
目录 模块 什么是模块? 模块的四种形式 为什么要用模块 如何用模块 import from...import... 异同 循环导入问题 解决方案 1. 2. 模块搜索路径 random模块 模块 什 ...
- 【统计】Causal Inference
[统计]Causal Inference 原文传送门 http://www.stat.cmu.edu/~larry/=sml/Causation.pdf 过程 一.Prediction 和 causa ...
- Java Script 基本知识点
JavaScript是一种基于对象和事件驱动的脚本语言,它提供了一些专有的类.对象及函数 1.基本数据类型 JavaScript提供了4种基本的数据类型用来 ...