bzoj4597: [Shoi2016]随机序列
Posted f321dd
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj4597: [Shoi2016]随机序列相关的知识,希望对你有一定的参考价值。
容易推出答案为$\sum_{i=1}^{n-1}2*3^{n-i-1}\prod_{j=1}^{i}a_{j}+\prod_{j=1}^{n}a_{j}$。然后随便怎么维护都行,我没多想直接用的区间乘区间和来搞,其实可以直接维护乘积和答案。
#include<cstdio> #define Z int l=1,int r=n,int k=1 #define N 100005 #define M (l+r>>1) #define P (k<<1) #define S (k<<1|1) #define L l,M,P #define R M+1,r,S int n,m,s,t; typedef long long ll; const ll p=1e9+7; ll f[N],e[N],a[N]; ll u[N*4],v[N*4]; void apply(ll a,int k){ u[k]=u[k]*a%p; v[k]=v[k]*a%p; } void devolve(int k){ if(v[k]!=1){ apply(v[k],P); apply(v[k],S); v[k]=1; } } void update(int k){ u[k]=(u[P]+u[S])%p; } void build(Z){ if(l==r) u[k]=a[l]; else{ build(L); build(R); update(k); } v[k]=1; } void amend(ll a,int s, int t,Z){ if(s<=l&&r<=t) apply(a,k); else{ devolve(k); if(s<=M) amend(a,s,t,L); if(t>M) amend(a,s,t,R); update(k); } } ll pow(ll u,ll k){ ll a=1; for(;k;k>>=1){ if(k%2)a=a*u%p; if(k/2)u=u*u%p; } return a; } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) scanf("%lld",e+i); f[f[0]=a[0]=1]=2; for(int i=2;i<n;++i) f[i]=f[i-1]*3%p; for(int i=1;i<=n;++i) a[i]=a[i-1]*e[i]%p; for(int i=1;i<=n;++i) a[i]=a[i]*f[n-i]%p; build(); while(m--){ scanf("%d%d",&s,&t); t=t*pow(e[s],p-2)%p; amend(t,s,n); e[s]=e[s]*t%p; printf("%lld\n",u[1]); } }
以上是关于bzoj4597: [Shoi2016]随机序列的主要内容,如果未能解决你的问题,请参考以下文章