4597: [Shoi2016]随机序列

Time Limit: 20 Sec  Memory Limit: 256 MB
Submit: 255  Solved: 174
[Submit][Status][Discuss]

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 取模。

Sample Input

5 5
9384 887 2778 6916 7794
2 8336
5 493
3 1422
1 28
4 60

Sample Output

890543652
252923708
942282590
228728040
608998099
 
 
题解:
  推一下式子,或者打一下表就可以发现+,-的都会抵消,只有和a1连在一起的乘发才产生贡献,并且对于a1*a2*a3……*an而言他前面的系数为3^(len-1-n)*2,(注意特判n==len的情况)。
  那么我们考虑用线段树来维护这个式子,每个叶子节点就是一个前缀积*他前面的系数,线段树维护区间和,每次对于x进行点修改,就相当于修改x~n的这一段区间,写一个lazy就可以了。
代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#define ll long long
#define MAXN 100100
#define mod 1000000007
using namespace std;
struct tree{
int l,r;ll lz,sum;
}a[MAXN*];
ll v[MAXN],vv[MAXN],pw[MAXN];
int n,q; void pushup(int xv){
a[xv].sum=a[xv*].sum+a[xv*+].sum;
//a[xv].sum%=mod;
if(a[xv].sum>=mod) a[xv].sum-=mod;
} void build(int xv,int l,int r){
if(l==r){
a[xv].l=l,a[xv].r=r,a[xv].lz=;
if(l==n) a[xv].sum=v[l];
else a[xv].sum=*v[l]*pw[n--l]%mod;
return;
}
a[xv].l=l,a[xv].r=r,a[xv].lz=;
int mid=(l+r)/;
build(xv*,l,mid),build(xv*+,mid+,r);
pushup(xv);
} ll ni(ll bas,ll ti){
ll ans=;
while(ti){
if(ti&) ans=(ans*bas)%mod;
bas=(bas*bas)%mod;ti>>=;
}
return ans;
} void pushdown(int xv){
if(a[xv].lz==) return;
a[xv*].sum=(a[xv*].sum*a[xv].lz)%mod;
a[xv*+].sum=(a[xv*+].sum*a[xv].lz)%mod;
a[xv*].lz=(a[xv*].lz*a[xv].lz)%mod;
a[xv*+].lz=(a[xv*+].lz*a[xv].lz)%mod;
a[xv].lz=;
} void change(int xv,int l,int r,ll x){
int L=a[xv].l,R=a[xv].r,mid=(L+R)/;
if(l==L&&R==r){
a[xv].sum=a[xv].sum*x%mod;
a[xv].lz=a[xv].lz*x%mod;
return;
}
pushdown(xv);
if(r<=mid) change(xv*,l,r,x);
else if(l>mid) change(xv*+,l,r,x);
else change(xv*,l,mid,x),change(xv*+,mid+,r,x);
pushup(xv);
} int main()
{
scanf("%d%d",&n,&q);
v[]=;for(int i=;i<=n;i++) scanf("%lld",&v[i]),vv[i]=v[i],v[i]=(v[i]*v[i-])%mod;
pw[]=;for(int i=;i<=n;i++) pw[i]=pw[i-]*,pw[i]%=mod;
build(,,n);
while(q--){
int ps,x;scanf("%d%d",&ps,&x);
ll xx=(x*ni(vv[ps],mod-))%mod;
vv[ps]=x;
change(,ps,n,xx);
printf("%lld\n",a[].sum);
}
return ;
}

BZOJ 4597: [Shoi2016]随机序列的更多相关文章

  1. BZOJ 4597: [Shoi2016]随机序列 线段树 + 思维

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

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

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

  3. P4340 [SHOI2016]随机序列

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

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

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

  5. BZOJ 4597 随机序列

    一定要想到,对于一个空位如果填了+,那么一定有一个表达式这里填-号使得后面的全部抵消掉.这点十分重要. 于是发现这个答案只和前缀积有关,线段树维护即可. #include<iostream> ...

  6. bzoj 4596 [Shoi2016]黑暗前的幻想乡 矩阵树定理+容斥

    4596: [Shoi2016]黑暗前的幻想乡 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 559  Solved: 325[Submit][Sta ...

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

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

  8. BZOJ4597: [Shoi2016]随机序列

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

  9. BZOJ 4596: [Shoi2016]黑暗前的幻想乡

    Sol 容斥原理+Matrix-Tree定理.容斥跟小星星那道题是一样的,然后...直接Matrix-Tree定理就可以了... 复杂度\(O(2^{n-1}n^3)\) PS:调了好久啊QAQ 明明 ...

随机推荐

  1. 【Offer】[49] 【丑数】

    题目描述 思路分析 测试用例 Java代码 代码链接 题目描述 我们把只包含因子2.3和5的数称作丑数( Ugly Number).求按从小到大的顺序的第1500个丑数.例如,6.8都是丑数,但14不 ...

  2. 一键升级所有pip过期库

    import pipfrom subprocess import callfrom pip._internal.utils.misc import get_installed_distribution ...

  3. 服务器扩容SAN存储

    串行登陆10.10.10.1/2/3/4 1.备份系统信息 mkdir -p /bakinfo df -h > /bakinfo/df.txt_`date +%Y%m%d%H%M%S` ps - ...

  4. 工业控制或办公局域网中的192.168.X.X网段

    IPv4地址分为A.B.C.D.E五类,除去特殊作用的D.E两类,剩下的A.B.C三类地址是我们常见的IP地址段.A类地址的容量最大,可以容纳16777214个主机,B类地址可以容纳65534个主机, ...

  5. Android开发--Intent的使用(1)启动活动

    Android系统是目前世界上市场占有率最高的移动操作系统,近年来,Android开发也越来越炙手可热. 在Android开发中,我们使用Intent进行活动Activity之间穿梭. 当我们点击启动 ...

  6. NPOI导出数值格式设置(我是保留四位小数,不足补0)

    看了网上好多帖子,都是保留两位小数的,写法是: HSSFDataFormat.GetBuiltinFormat("0.00"); 于是想四位小数,就是多加两个00,变成: HSSF ...

  7. EF指定更新字段

    使用EF做更新时,若没有进行跟踪会默认全字段更新,那怎么做到只更新我们想要更新的字段呢? /// <summary> /// 修改指定属性的单条数据 /// </summary> ...

  8. maven的mirror和repository加载顺序

    一.概述 maven的settings.xml文件里面有proxy.server.repository.mirror的配置,在配置仓库地址的时候容易混淆 proxy是服务器不能直接访问外网时需要设置的 ...

  9. JAVASE知识点总结(四)

    第十七章:内部类和枚举 一.内部类 1.什么是内部类? 2.为什么要有内部类? 3.内部类的种类: 5.实例内部类 6.创建实例内部类 7.实例内部类注意点 8.访问变量原则: 4 9.静态内部类: ...

  10. JAVASE知识点总结(二)

    第十三章:多态  一.instanceof 判断一个类是否是指定的类 真则返回true 假则返回false.  二.字段没有多态,只有方法有多态,字段前面是的什么类型,字段就调用谁的,在编译时就已经确 ...