单点更新,更新时先除去 原来的数,因为有去摸,可以用乘上逆元代替。

 

//============================================================================
// Name        : A.cpp
// Author      : L_Ecry
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define N 50050
#define MOD 1000000007
#define LL long long
using 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;
}
View Code

 

posted on 2014-07-27 15:14  L_Ecry  阅读(196)  评论(0编辑  收藏  举报