可以发现加减号之间可以互相抵消.
真正加到答案里的只有一些前缀积.
记s[i]为a[1]*a[2]*a[3]...*a[i].那s[i]在答案中出现的次数就是2*3^(n-i-1);
修改一个数只会对后面的数有影响.
预处理逆元然后用线段树维护即可.

#include<iostream>
#include<cstdio>
#include<cstring>
#define N 100010
#define P 1000000007
using namespace std;
long long t[N<<2],inv[N],a[N],s[N],bin[N],x,p[N<<2];
int n,q,pos;
void build(int k,int l,int r){
int mid=(l+r)>>1;
if (l==r){
if (l!=n) t[k]=(s[l]*bin[n-l-1]*2)%P;
else t[k]=s[l];
return;
}
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
t[k]=(t[k<<1]+t[k<<1|1])%P;
}
void paint(int k,long long v){
t[k]=(t[k]*v)%P;
p[k]=(p[k]*v)%P;
}
void pushdown(int k,int l,int r){
int mid=(l+r)>>1;
paint(k<<1,p[k]);
paint(k<<1|1,p[k]);
p[k]=1;
}
void change(int k,int l,int r,int ll,int rr,long long v){
int mid=(l+r)>>1;
if (ll<=l&&r<=rr){paint(k,v);return;}
if (p[k]!=1) pushdown(k,l,r);
if (ll<=mid) change(k<<1,l,mid,ll,rr,v);
if (mid<rr) change(k<<1|1,mid+1,r,ll,rr,v);
t[k]=(t[k<<1]+t[k<<1|1])%P;
}
int main(){
scanf("%d%d",&n,&q);
for (int i=1;i<=n;i++) scanf("%lld",&a[i]);
bin[0]=1;
for (int i=1;i<=n;i++) bin[i]=(bin[i-1]*3)%P;
inv[1]=1;
for(int i=2;i<=10000;i++)
inv[i]=(P-(long long)P/i*inv[P%i]%P);
s[1]=a[1];
for (int i=2;i<=n;i++) s[i]=(s[i-1]*a[i])%P;
build(1,1,n);
for (int i=1;i<=n*2;i++) p[i]=1;
for (int i=1;i<=q;i++){
scanf("%d%lld",&pos,&x);
change(1,1,n,pos,n,x*inv[a[pos]]%P);
a[pos]=x;printf("%lld\n",t[1]);
}
}

  

【bzoj4597】 [Shoi2016]随机序列的更多相关文章

  1. BZOJ4597 SHOI2016随机序列(线段树)

    先考虑题目所说的太简单了的问题.注意到只要把加减号相取反,就可以得到一对除了第一项都互相抵消的式子.于是得到答案即为Σf(i)g(i),其中f(i)为前缀积,g(i)为第i个数前面所有符号均填乘号,第 ...

  2. BZOJ4597: [Shoi2016]随机序列

    Description 你的面前有N个数排成一行.分别为A1, A2, … , An.你打算在每相邻的两个 Ai和 Ai+1 间都插入一个加号或者 减号或者乘号.那么一共有 3^(n-1) 种可能的表 ...

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

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

  4. P4340 [SHOI2016]随机序列

    题目 P4340 [SHOI2016]随机序列 思维好题 做法 是否觉得水在于你是否发现加减是会抵消的,所以我们只用考虑乘的部分 一块乘只能前面无号(也就是前缀形式)才统计,所以用线段树维护区间前缀乘 ...

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

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

  6. BZOJ4597:[SHOI2016]随机序列——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4597 你的面前有N个数排成一行.分别为A1, A2, … , An.你打算在每相邻的两个 Ai和 ...

  7. [洛谷P4340][SHOI2016]随机序列

    题目大意:有$n(n\leqslant10^5)$个数,每两个数之间可以加入$+-\times$三种符号,$q(q\leqslant10^5)$次询问,每次询问修改一个数后,所有表达式可能的值的和 题 ...

  8. SHOI2016 随机序列

    给你一个数列,在相邻两个数之间插入加号,减号或乘号 每次支持单点修改,求所有这样可以得到的表达式之和,膜1e9 + 7 sol: 我是个 sb ... 可以发现,如果某位置出现了加号,后面一定有一个减 ...

  9. bzoj 4597||洛谷P4340 [Shoi2016]随机序列

    https://www.lydsy.com/JudgeOnline/problem.php?id=4597 https://www.luogu.org/problemnew/show/P4340 妄图 ...

随机推荐

  1. linux下设置python3.x为默认版本

    rm /usr/bin/python ln -s /usr/local/bin/python3.x /usr/bin/python sybomlic 安装目录 系统目录

  2. element--ui使用tab切换时如何获取当前对象的id或者其他属性

    1. 问题 当使用tab切换时,部分特殊场景需要获取当前元素的类名或者id. 2.解决思路,tab切换是绑定函数,函数会传递过去当前对象,通过当前对象获取对象属性 vue部分代码:本项目是在vue-c ...

  3. cc.Label

    cc.Label 1:cc.Label是显示文字的组件;2:cc.Label属性面板:  String: 文本显示的内容;  Horiznotal: 水平对齐的方式: 左 右 居中;  Vertial ...

  4. npm run build报错(npm ERR! code ELIFECYCLE)的解决办法

    具体报错如下图: 环境:centos7 应该node_modules安装问题,我们需要重新安装 rm -rf node_modules rm package-lock.json npm cache c ...

  5. mysql8忘记登录密码时,修改密码方法

    一.停止mysqld进程 systemctl stop mysqld.service 二.修改/etc/my.cnf(在mysqld选项添加skip-grant-tables),设置免密码登录: vi ...

  6. Buffer.alloc()

    Buffer.alloc(size[, fill[, encoding]]) Node.js FS模块方法速查 size {Number} fill {Value} 默认:undefined enco ...

  7. *** 红包书用法 及 ubuntu全局配置

    使用教程 http://go.wasai.org/sswiki https://home.maysoul.com/wiki/doku.php?id=shadowsocks ubuntu使用教程 htt ...

  8. 使用JS对form的内容验证失败后阻止提交

    1.form的两个事件 submit,提交表单,如果直接调用该函数,则直接提交表单 onSubmit,提交按钮点击时先触发,然后触发submit事件.如果不加控制的话,默认返回true,因此表单总能提 ...

  9. 确定协议-通过分析系统阶段需要知道该系统能不能进行性能测试-Omnipeek

  10. Leetcode 143.重排链表

    重排链表 给定一个单链表 L:L0→L1→…→Ln-1→Ln ,将其重新排列后变为: L0→Ln→L1→Ln-1→L2→Ln-2→… 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换. 示 ...