题目;http://acm.hdu.edu.cn/showproblem.php?pid=5475
题意就是给X赋初值1,然后给Q个操作,每个操作对应一个整数M;如果操作是1则将X乘以对应的M,如果是2则除以第M次操作对应的M',求最后X的值对给定值取摸的结果,
直接暴力会爆long long,用数组存每一步的话 会超时,所以用线段树优化进行区间更新
1 #include<cstdio> 2 using namespace std; 3 typedef long long ll; 4 struct point { 5 int l,r; 6 ll sum; 7 }; 8 point tree[100001*8]; 9 int n,m; 10 void build(int i,int left,int right) 11 { 12 tree[i].l=left; 13 tree[i].r=right; 14 if (left==right) 15 { 16 tree[i].sum=1; 17 return; 18 } 19 int mid=(left+right)>>1; 20 build(i<<1,left,mid); 21 build(i<<1|1,mid+1,right); 22 tree[i].sum=(tree[i<<1].sum*tree[i<<1|1].sum)%m; 23 } 24 void update(int i,int num,int val) 25 { 26 if (tree[i].l==tree[i].r) 27 { 28 tree[i].sum=val; 29 return; 30 } 31 int mid=(tree[i].l+tree[i].r)>>1; 32 if (num<=mid) update(i<<1,num,val); 33 else update(i<<1|1,num,val); 34 tree[i].sum=(tree[i<<1].sum*tree[i<<1|1].sum)%m; 35 } 36 ll _find(int i,int left,int right) 37 { 38 ll ans=1; 39 if (left<=tree[i].l&&tree[i].r<=right) 40 return tree[i].sum; 41 int mid=(tree[i].l+tree[i].r)>>1; 42 if (left<=mid) ans*=_find(i<<1,left,right)%m; 43 if (right>mid) ans*=_find(i<<1|1,left,right)%m; 44 return ans%m; 45 } 46 int main() 47 { 48 int t,x,y,i,w=1; 49 scanf("%d",&t); 50 while (t--) 51 { 52 printf("Case #%d:\n",w++); 53 scanf("%d %d",&n,&m); 54 build(1,1,n); 55 for (i=1;i<=n;i++) 56 { 57 scanf("%d %d",&x,&y); 58 if (x==1) 59 { 60 update(1,i,y); 61 printf("%I64d\n",_find(1,1,i)%m); 62 } 63 else 64 { 65 update(1,y,1); 66 printf("%I64d\n",_find(1,1,i)%m); 67 } 68 } 69 } 70 return 0; 71 }