[bzoj4597][Shoi2016]随机序列 线段树
来源:互联网 发布:决战武林宠物升级数据 编辑:程序博客网 时间:2024/05/22 10:46
4597: [Shoi2016]随机序列
Time Limit: 20 Sec Memory Limit: 256 MB[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
9384 887 2778 6916 7794
2 8336
5 493
3 1422
1 28
4 60
Sample Output
890543652
252923708
942282590
228728040
608998099
252923708
942282590
228728040
608998099
HINT
看来我被这道题骗了
一个等式
{前}+{后}
{前}-{后}
加起来
等于
2*{前}
于是此题就是维护一个值
fac[i]表示a[1]*a[2]*a[3]...a[i]
sigma 2*fac[i]*3^(n-i-1) + fac[n]
为什么?(还需要解释吗)
fac[i]仅存在于第i位是+或-号,前面均为*,+ - * 有(n-1)- i 位,就是3的那么多次方
所以区间乘法就完了
为甚么我的线段树常数下不来!!!
逆元用欧拉定理预处理(只有10000)
#include <bits/stdc++.h>using namespace std;const int N = 1000000 + 5;const int mod = 1e9 + 7;int inv[10005],n,q,fac[N],a[N],sum[N<<2],flag[N<<2];int quik_pow( int x, int p ){int ret = 1;while( p ){if( p & 1 ) ret = 1LL * ret * x % mod;x = 1LL * x * x % mod;p >>= 1;}return ret;}void pushdown( int k ){if( flag[k] != 1 ){flag[k<<1] = 1LL * flag[k<<1] * flag[k] % mod;flag[k<<1|1] = 1LL * flag[k<<1|1] * flag[k] % mod;sum[k<<1] = 1LL * sum[k<<1] * flag[k] % mod;sum[k<<1|1] = 1LL * sum[k<<1|1] * flag[k] % mod;flag[k] = 1;}}void update( int k ){sum[k] = ( sum[k<<1] + sum[k<<1|1] ) % mod;}void build( int k, int l, int r ){flag[k] = 1;if( l == r ){if( l == n ) sum[k] = fac[l];else sum[k] = 1LL * fac[l] * ( 2LL * quik_pow( 3, n - l - 1 ) % mod ) % mod;return ;}int mid = l + r >> 1;build( k<<1, l, mid );build( k<<1|1, mid+1, r );update( k );}void change( int k, int l, int r, int L, int R, int x ){if( l >= L && r <= R ){sum[k] = 1LL * sum[k] * x % mod;flag[k] = 1LL * flag[k] * x % mod;return ;}pushdown( k );int mid = l + r >> 1;if( mid >= L ) change( k<<1, l, mid, L, R, x );if( mid < R ) change( k<<1|1, mid+1, r, L, R, x );update( k );}int main(){fac[0] = 1;for( int i = 1; i <= 10000; i++ ) inv[i] = quik_pow( i, mod-2 );scanf( "%d%d", &n, &q );for( int i = 1; i <= n; i++ ) scanf( "%d", &a[i] ), fac[i] = 1LL * fac[i-1] * a[i] % mod;build( 1, 1, n );while( q-- ){int x,y;scanf( "%d%d", &x, &y ); int yy= 1LL * y * inv[a[x]] % mod;change( 1, 1, n, x, n, yy ); a[x] = y;printf( "%d\n", sum[1] );}return 0;}明天我就16岁了,成为一位长者
阅读全文
0 0
- 【bzoj4597】[Shoi2016]随机序列 线段树
- 【BZOJ4597】【Shoi2016】随机序列 线段树
- 【bzoj4597】【Shoi2016】【随机序列】【线段树】
- [bzoj4597][Shoi2016]随机序列 线段树
- [BZOJ4597][SHOI2016]随机序列(线段树)
- BZOJ4597 [Shoi2016]随机序列
- bzoj4597 [Shoi2016]随机序列
- BZOJ4597: [Shoi2016]随机序列
- [bzoj4597/Shoi2016]随机序列
- 4597: [Shoi2016]随机序列
- bzoj 4597: [Shoi2016]随机序列
- BZOJ 4597: [Shoi2016]随机序列
- 【线段树】序列操作
- 时间序列线段树
- 【SCOI2010】【线段树】序列操作
- 【bzoj2962】【序列操作】【线段树】
- bzoj1858序列操作 线段树
- 【BZOJ4540】【Hnoi2016】序列 线段树
- 去掉IntelliJ IDEA 中 mybatis 对应的 xml 文件警告
- 史上最全开发者工具详解,在开发者工具里如何判断一个请求是ajax请求
- 运行时数据区
- IntelliJ IDEA报class is never used
- 玩转windbg软件调试视频教程发布-windbg入门教程
- [bzoj4597][Shoi2016]随机序列 线段树
- 浅谈AP聚类算法-matlab
- 开博首篇
- SpringCloud基础(5)
- 归并排序
- 挑战程序竞赛系列(91):3.6凸包(2)
- Thread类的sleep()方法和对象的wait()方法都能使线程暂停执行,他们有什么区别?
- 《红楼梦》的方位观念
- OSG可绘制体Drawable