首页 > 代码库 > hdu 3074 Multiply game

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