hdu 3074 Multiply game
Posted ws_ccd
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 3074 Multiply game相关的知识,希望对你有一定的参考价值。
普通的区间问题,用线段树就行了。
(用树状数组维护逆元和乘积作了一下死2333,TLE(应该是模数太大了,要用快速乘才能取到模,所以多了一个log))
(代码注释掉的是线段树,没注释的是T掉的树状数组)
1 #include<bits/stdc++.h> 2 #define N 100005 3 #define M 10000005 4 #define lowbit(x) x&(-x) 5 #define LL long long 6 #define inf 0x3f3f3f3f 7 using namespace std; 8 inline int ra() 9 { 10 int x=0,f=1; char ch=getchar(); 11 while (ch<‘0‘ || ch>‘9‘) {if (ch==‘-‘) f=-1; ch=getchar();} 12 while (ch>=‘0‘ && ch<=‘9‘) {x=x*10+ch-‘0‘; ch=getchar();} 13 return x*f; 14 } 15 const LL mod=1000000007LL; 16 struct seg{ 17 int l,r; LL mul; 18 }t[N<<2]; 19 int n; 20 LL a[N]; 21 void update(int k) 22 { 23 t[k].mul=(t[k<<1].mul*t[k<<1|1].mul)%mod; 24 } 25 void build(int k, int l, int r) 26 { 27 t[k].l=l; t[k].r=r; 28 if (l==r) {t[k].mul=(LL)a[l]; return;} 29 int mid=l+r>>1; 30 build(k<<1,l,mid); build(k<<1|1,mid+1,r); 31 update(k); 32 } 33 void change(int k, int x, LL val) 34 { 35 int l=t[k].l,r=t[k].r; 36 if (l==r) 37 { 38 t[k].mul=val; t[k].mul%=mod; 39 return; 40 } 41 int mid=l+r>>1; 42 if (x<=mid) change(k<<1,x,val); 43 else change(k<<1|1,x,val); 44 update(k); 45 } 46 LL ask(int k, int x, int y) 47 { 48 int l=t[k].l,r=t[k].r; 49 if (l==x && y==r) return t[k].mul; 50 int mid=l+r>>1; 51 if (y<=mid) return ask(k<<1,x,y); 52 else if (x>mid) return ask(k<<1|1,x,y); 53 else return (ask(k<<1,x,mid)*ask(k<<1|1,mid+1,y))%mod; 54 } 55 LL ksc(int x, int p) 56 { 57 LL sum=0; 58 for (;p;p>>=1,x=(x+x)%mod) 59 if (p&1) sum=(sum+x)%mod; 60 return sum; 61 } 62 LL get(int x) 63 { 64 LL sum=1; int p=(int)mod-2; 65 for (;p;p>>=1,x=ksc(x,x)%mod) 66 if (p&1) sum=ksc(sum,x)%mod; 67 return sum%mod; 68 } 69 /*int main() 70 { 71 int T=ra(); 72 while (T--) 73 { 74 n=ra(); for (int i=1; i<=n; i++) a[i]=(LL)ra(); 75 build(1,1,n); 76 int Q=ra(); 77 while (Q--) 78 { 79 int opt=ra(),x=ra(),y=ra(); 80 if (opt==0) printf("%lld\n",ask(1,x,y)%mod); 81 else change(1,x,(LL)y),a[x]=y; 82 } 83 } 84 }*/ 85 LL c[N],ry[N]; 86 void add(int x, int val, int valry) 87 { 88 for (;x<=n;x+=lowbit(x)) c[x]*=val,c[x]%=mod,ry[x]*=valry,ry[x]%=mod; 89 } 90 LL ask(int x){LL sum=1; for (;x;x-=lowbit(x)) sum*=c[x],sum%=mod; return sum;} 91 LL askry(int x){LL sum=1; for (;x;x-=lowbit(x)) sum*=ry[x],sum%=mod; return sum;} 92 int main() 93 { 94 int T=ra(); 95 while (T--) 96 { 97 n=ra(); 98 for (int i=0; i<=n; i++) c[i]=ry[i]=1LL; 99 for (int i=1; i<=n; i++) a[i]=(LL)ra(),add(i,a[i],get(a[i])); 100 int Q=ra(); 101 while (Q--) 102 { 103 int opt=ra(),x=ra(),y=ra(); 104 if (opt==0) printf("%lld\n",askry(x-1)*ask(y)%mod); 105 else add(x,get(a[x])*y%mod,a[x]*get(y)%mod),a[x]=y; 106 } 107 } 108 }
以上是关于hdu 3074 Multiply game的主要内容,如果未能解决你的问题,请参考以下文章
hdu-3074 Multiply game---线段树+单点更新