单点更新,更新时先除去 原来的数,因为有去摸,可以用乘上逆元代替。
//============================================================================// Name : A.cpp// Author : L_Ecry// Version :// Copyright : Your copyright notice// Description : Hello World in C++, Ansi-style//============================================================================#include#include #include #include #include #define N 50050#define MOD 1000000007#define LL long longusing namespace std;LL value[N*4];int a[N];int n;int extgcd(int a,int b,int &x,int &y){ int t,d; if(b==0){ x=1;y=0; return a; } d=extgcd(b,a%b,x,y); t=x; x=y; y=t-a/b*y; return d;}int invmod(int a,int n){ int x,y; if(extgcd(a,n,x,y)!=1)return -1; return (x%n+n)%n;}void build(int l,int r,int i){ if(l==r){ value[i]=a[l]; return; } int mid=(l+r)>>1; int lson=(i<<1),rson=(i<<1|1); build(l,mid,lson); build(mid+1,r,rson); value[i]=(value[lson]*value[rson])%MOD;}void update(int l,int r,int p,int va,int i){ if(l==r) { value[i]=va; return; } value[i]=(value[i]*invmod(a[p],MOD))%MOD; value[i]=(value[i]*va)%MOD; int mid=(l+r)>>1; if(p<=mid)update(l,mid,p,va,i<<1); else update(mid+1,r,p,va,i<<1|1);}LL query(int l,int r,int pl,int pr,int i){ if(l==pl&&r==pr) return value[i]; int mid=(l+r)>>1; if(mid>=pr)return query(l,mid,pl,pr,i<<1); else if(pl>mid)return query(mid+1,r,pl,pr,i<<1|1); else { return (query(l,mid,pl,mid,i<<1)*query(mid+1,r,mid+1,pr,i<<1|1))%MOD; }}void init(){ scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",&a[i]); build(1,n,1);}void solve(){ int q; scanf("%d",&q); while(q--) { int x,y,z; scanf("%d%d%d",&x,&y,&z); if(x==1) { update(1,n,y,z,1); a[y]=z; }else { printf("%lld\n",query(1,n,y,z,1)); } }}int main() { int tt; scanf("%d",&tt); while(tt--) { init(); solve(); } return 0;}