首页 > 代码库 > HDU 3074 Multiply game(线段树)
HDU 3074 Multiply game(线段树)
单点更新,更新时先除去 原来的数,因为有去摸,可以用乘上逆元代替。
//============================================================================// 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 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;}
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。