BZOJ4597:[SHOI2016]随机序列——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4597
你的面前有N个数排成一行。分别为A1, A2, … , An。你打算在每相邻的两个 Ai和 Ai+1 间都插入一个加号或者减号或者乘号。那么一共有 3^(n-1) 种可能的表达式。你对所有可能的表达式的值的和非常感兴趣。但这毕竟太简单了,所以你还打算支持一个修改操作,可以修改某个Ai 的值。你能够编写一个程序对每个修改都输出修改完之后所有可能表达式的和吗?注意,修改是永久的,也就是说每次修改都是在上一次修改的基础上进行, 而不是在最初的表达式上进行。
(讲个事为了防止我忘了这题怎么做从而写不了题解所以这题解是我边想题边写的233所以可能啰嗦些)
首先我们肯定不可能暴力求和,那么我们打打表看看会怎么样。
当n=2时为2*a1+a1*a2,当n=3时为6*a1+2*a1*a2+a1*a2*a3,当n=4时18*a1+6*a1*a2+2*a1*a2*a3+a1*a2*a3*a4……
我们发现每次的系数都为后一项*3,然而将这个数列放到oeis上查能查到好多,这个结论不一定可靠,于是试图证明它(当然你可以跳过证明,毕竟不严格)。
证明:我们只看a1项系数,于是放乘号的位置只有2^(n-2)个,并且设放乘号个数为i,则乘号合并后的数字显然只有(n-i)个。
此时我们再往合并后的数字里面填符号的话,只有+/-的情况下显然=2^(n-i-1)*a1(剩余的项都被消了)
于是我们得到了a1的个数:sigma(C(n-2,i)*2^(n-i-1))(0<=i<=n-2)。
这个式子很像二项式定理,于是除2再乘2得到2*(2+1)^(n-2)=2*3^(n-2)。
第一项我们证明出来了,那么第二项,第三项……都可以直接推出来,证毕。
那么直接线段树维护即可,懒得说怎么维护了。
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1e5+;
const int p=1e9+;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
int qpow(int k,int n){
int res=;
while(n){
if(n&)res=(ll)res*k%p;
k=(ll)k*k%p;n>>=;
}
return res;
}
int n,m,c[N],tr[N*],b[N],q[N],lz[N*];
inline int add(int x,int y){
x+=y;if(x>=p)x-=p;return x;
}
inline int mul(ll x,int y){
return x*y%p;
}
inline void push(int a){
if(lz[a]!=-){
tr[a<<]=mul(tr[a<<],lz[a]);
tr[a<<|]=mul(tr[a<<|],lz[a]);
if(lz[a<<]==-)lz[a<<]=lz[a];
else lz[a<<]=mul(lz[a<<],lz[a]);
if(lz[a<<|]==-)lz[a<<|]=lz[a];
else lz[a<<|]=mul(lz[a<<|],lz[a]);
lz[a]=-;
}
}
void build(int a,int l,int r){
lz[a]=-;
if(l==r){
tr[a]=mul(q[l],b[l]);return;
}
int mid=(l+r)>>;
build(a<<,l,mid);build(a<<|,mid+,r);
tr[a]=add(tr[a<<],tr[a<<|]);
}
void modify(int a,int l,int r,int l1,int r1,int w){
if(r<l1||r1<l)return;
if(l1<=l&&r<=r1){
if(lz[a]==-)lz[a]=w;
else lz[a]=mul(lz[a],w);
tr[a]=mul(tr[a],w);
return;
}
push(a);
int mid=(l+r)>>;
modify(a<<,l,mid,l1,r1,w);modify(a<<|,mid+,r,l1,r1,w);
tr[a]=add(tr[a<<],tr[a<<|]);
}
int main(){
n=read(),m=read();b[]=;
for(int i=;i<=n;i++){
c[i]=read();
b[i]=mul(b[i-],c[i]);
}
q[n]=,q[n-]=;
for(int i=n-;i>=;i--)q[i]=mul(q[i+],);
build(,,n);
while(m--){
int k=read(),v=read();
modify(,,n,k,n,(ll)v*qpow(c[k],p-)%p);
c[k]=v;
printf("%d\n",tr[]);
}
return ;
}
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++
BZOJ4597:[SHOI2016]随机序列——题解的更多相关文章
- BZOJ4597 SHOI2016随机序列(线段树)
先考虑题目所说的太简单了的问题.注意到只要把加减号相取反,就可以得到一对除了第一项都互相抵消的式子.于是得到答案即为Σf(i)g(i),其中f(i)为前缀积,g(i)为第i个数前面所有符号均填乘号,第 ...
- BZOJ4597: [Shoi2016]随机序列
Description 你的面前有N个数排成一行.分别为A1, A2, … , An.你打算在每相邻的两个 Ai和 Ai+1 间都插入一个加号或者 减号或者乘号.那么一共有 3^(n-1) 种可能的表 ...
- 【BZOJ4597】[Shoi2016]随机序列 线段树
[BZOJ4597][Shoi2016]随机序列 Description 你的面前有N个数排成一行.分别为A1, A2, … , An.你打算在每相邻的两个 Ai和 Ai+1 间都插入一个加号或者减号 ...
- BZOJ 4597: [Shoi2016]随机序列
4597: [Shoi2016]随机序列 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 255 Solved: 174[Submit][Status ...
- P4340 [SHOI2016]随机序列
题目 P4340 [SHOI2016]随机序列 思维好题 做法 是否觉得水在于你是否发现加减是会抵消的,所以我们只用考虑乘的部分 一块乘只能前面无号(也就是前缀形式)才统计,所以用线段树维护区间前缀乘 ...
- 【bzoj4597】 [Shoi2016]随机序列
可以发现加减号之间可以互相抵消. 真正加到答案里的只有一些前缀积. 记s[i]为a[1]*a[2]*a[3]...*a[i].那s[i]在答案中出现的次数就是2*3^(n-i-1); 修改一个数只会对 ...
- [洛谷P4340][SHOI2016]随机序列
题目大意:有$n(n\leqslant10^5)$个数,每两个数之间可以加入$+-\times$三种符号,$q(q\leqslant10^5)$次询问,每次询问修改一个数后,所有表达式可能的值的和 题 ...
- bzoj 4597||洛谷P4340 [Shoi2016]随机序列
https://www.lydsy.com/JudgeOnline/problem.php?id=4597 https://www.luogu.org/problemnew/show/P4340 妄图 ...
- BZOJ4557:[JLOI2016/SHOI2016]侦察守卫——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4557 小R和B神正在玩一款游戏.这款游戏的地图由N个点和N-1条无向边组成,每条无向边连接两个点, ...
随机推荐
- 抽样分布(3) F分布
定义 设U~χ2(n1), V~χ2(n2),且U,V相互独立,则称随机变量 服从自由度为(n1,n2)的F分布,记为F~F(n1,n2),其中n1叫做第一自由度,n2叫做第二自由度. F分布的概率密 ...
- 怎样从Java转换到Kotlin代码:现在就开始使用Kotlin(KAD 29)
作者:Antonio Leiva 时间:Jul, 4, 2017 原文链接:https://antonioleiva.com/kotlin-from-java/ Kotlin最神奇特性之一是它能与Ja ...
- python操作符及其循环语句(非常全)
//2018.10.14 1. Windows + R可以直接进行运行cmd 2. Random.randint(a,b):产生a-b的任意一个整数,在IDLE里面运行时需要注意在前面写好调用impo ...
- struts2源码分析-初始化流程
这一篇文章主要是记录struts.xml的初始化,还原struts2.xml的初始化流程.源码依据struts2-2.3.16.3版本. struts2初始化入口,位于web.xml中: <fi ...
- [C++ map & dp]codeforces 960F. Pathwalks
题目传送门:960F 思路: 题目给人的感觉很像最长上升子序列,自然而然想到用dp的思路去处理 题目中给的限制条件是,要接上前面的边,前面的边权一定要小于当前的边权(题目按照输入的顺序,因此只找前面的 ...
- 使用清华镜像在python中pip 安装
Anaconda的安装步骤不在本文的讨论中,我们主要是学习一下如何配置conda的镜像,以及一些问题的解决过程 配置镜像 在conda安装好之后,默认的镜像是官方的,由于官网的镜像在境外,我们使用国内 ...
- java一些面试题
java虚拟机 什么时候会触发full gc System.gc()方法的调用 老年代空间不足 永生区空间不足(JVM规范中运行时数据区域中的方法区,在HotSpot虚拟机中又被习惯称为永生代或者永生 ...
- HADOOP docker(十):hdfs 结构体系
1.简介2.namenode和datanode3.The File System Namespace 文件系统命名空间4.Data Replication 数据复制5.Replica Placemen ...
- 【转】Hbuilder MUI 页面刷新及页面传值问题
文章来源:http://www.111cn.net/sys/CentOS/67213.htm 一.页面刷新问题 1.父页面A跳转到子页面B,B页面修改数据后再跳回A页面,刷新A页面数据 (1).父页面 ...
- Python—集合(在我的世界,你就是唯一)
一.概念与定义 集合类型与数学中集合的概念一致,即包含0个或多个数据项的无序组合. 元素不可重复,只能是固定数据类型元素. 集合(set)属于Python无序可变序列,使用一对大括号作为定界符,元素之 ...