标签:
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2189 Accepted Submission(s):
783
#define mod 1000000007 #include<iostream> using namespace std; #include<cstdio> #include<cstring> #define N 50010 struct Tree{ long long sum; }tree[N*4];/*数组要开到四倍,因为会有许多空节点使用不到*/ int n,t,q,k1,k2,p,x; int a[N]; void update(int k) { int lch=k<<1,rch=(k<<1)+1;/*不知道为甚,宏定义会出错误*/ tree[k].sum=(tree[lch].sum*tree[rch].sum)%mod; } void build_tree(int k,int l,int r) { int lch=k<<1,rch=(k<<1)+1,mid=(l+r)>>1; if(l==r) { tree[k].sum=a[l]%mod; return ; } build_tree(lch,l,mid); build_tree(rch,mid+1,r); update(k); } long long query(int k,int l,int r,int k1,int k2) { int lch=k<<1,rch=(k<<1)+1,mid=(l+r)>>1; if(k1<=l&&r<=k2) { return tree[k].sum%mod; } long long ans=1; if(k1<=mid) ans=(ans*query(lch,l,mid,k1,k2))%mod; if(k2>mid) ans=(ans*query(rch,mid+1,r,k1,k2))%mod; return ans; } void change(int k,int l,int r,int pos,int pl) { int lch=k<<1,rch=(k<<1)+1,mid=(l+r)>>1; if(l==r)/*一开始加了懒惰标记,结果下传的时候处理的和区间下传一样了,结果错了,改为直接找到单点,再往回更新*/ { tree[k].sum=pl; return; } if(pos<=mid) change(lch,l,mid,pos,pl); else change(rch,mid+1,r,pos,pl); update(k); } int main() { scanf("%d",&t); while(t--) { memset(tree,0,sizeof(tree)); memset(a,0,sizeof(a)); scanf("%d",&n); for(int i=1;i<=n;++i) { scanf("%d",&a[i]); } build_tree(1,1,n); scanf("%d",&q); for(int i=1;i<=q;++i) { scanf("%d",&x); if(x==0) { scanf("%d%d",&k1,&k2); cout<<query(1,1,n,k1,k2)<<endl; } else { scanf("%d%d",&k1,&p); change(1,1,n,k1,p); a[k1]=p; } } } return 0; }
线段树 求区间连乘——hdu 3074 Multiply game
标签:
原文地址:http://www.cnblogs.com/c1299401227/p/5479802.html