一开始看题一脸不可做的样子。。肯定又有什么鬼畜的结论
QAQ
。
(看看题解之后)。。和加减没什么关系。。维护一下前缀积的和就好了。
QAQ
然后自己拿
n=3
手写试了一发。。md为什么不自己想。。
ans=∑i=1n−1(2∗3n−i−1∗∏j=1iai)+∏j=1nai
线段树维护一下就好了嘛。。然后每次将 ax 修改为 y ,影响的只有
【代码】
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#define N 100005
#define Mod 1000000007
#define INF 200001
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ull base=31;
ll read()
{
ll x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
int n,m;
ll a[N],prod[N];
ll Inv[10004];
class Seg_Tree{
public:
int l,r;ll sum,tag;
}e[N<<2];
ll Qpow(ll x,int y)
{
ll rtn=1;
while(y>0) {
if(y&1) rtn=rtn*x%Mod;
x=x*x%Mod;y>>=1;
}
return rtn;
}
void pushup(int p){
e[p].sum=(e[p<<1].sum+e[p<<1|1].sum)%Mod;
}
void pushdown(int p)
{
ll t=e[p].tag;e[p].tag=1;
e[p<<1].tag=e[p<<1].tag*t%Mod;
e[p<<1|1].tag=e[p<<1|1].tag*t%Mod;
e[p<<1].sum=e[p<<1].sum*t%Mod;
e[p<<1|1].sum=e[p<<1|1].sum*t%Mod;
}
void Build(int p,int l,int r)
{
e[p].l=l,e[p].r=r,e[p].tag=1;
if(l==r) {
e[p].sum=(l!=n)?1LL*2*prod[l]%Mod*Qpow(3,n-l-1)%Mod:prod[n];
return;
}
int mid=l+r>>1;
Build(p<<1,l,mid);Build(p<<1|1,mid+1,r);
pushup(p);
}
void Update(int p,int x,int y,ll z)
{
int l=e[p].l,r=e[p].r,mid=l+r>>1;
if(l==x&&y==r) {
e[p].tag=e[p].tag*z%Mod;
e[p].sum=e[p].sum*z%Mod;
return;
}
if(e[p].tag!=1) pushdown(p);
if(y<=mid) Update(p<<1,x,y,z);
else if(x>mid) Update(p<<1|1,x,y,z);
else Update(p<<1,x,mid,z),Update(p<<1|1,mid+1,y,z);
pushup(p);
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
n=read(),m=read();Inv[1]=1;
for(int i=1;i<=n;i++) a[i]=read();
for(int i=2;i<=1e4;i++)
Inv[i]=(Mod-Mod/i)*Inv[Mod%i]%Mod;
prod[0]=1;
for(int i=1;i<=n;i++) prod[i]=a[i]*prod[i-1]%Mod;
Build(1,1,n);
for(int i=1;i<=m;i++)
{
static int pos;ll x;
pos=read(),x=read();
ll t=Inv[a[pos]]*x%Mod;a[pos]=x;
Update(1,pos,n,t);
printf("%lld\n",e[1].sum);
}
return 0;
}