http://acm.hdu.edu.cn/showproblem.php?pid=5475
题意:
原数开始时是1按顺序给你Q个操作,然后其中操作分两种。
1表示将上个操作后的数乘以后面给你的数然后对取余,然后输出结果,2表示除的操作,将现在的数除以指定的先前你所乘上的第几个数
然后对M取模。
思路:
这题用线段树写,断点更新,复杂度是n*(log(n));
代码:
1 #include<stdio.h> 2 #include<algorithm> 3 #include<iostream> 4 #include<string.h> 5 #include<stdlib.h> 6 typedef long long LL; 7 void up(LL k,LL l); 8 void build(LL l,LL r,LL k); 9 LL que(LL l,LL r,LL k,LL aa,LL dd); 10 typedef struct pp 11 { 12 LL x; 13 LL y; 14 LL id; 15 LL t; 16 } ss; 17 typedef struct tree1 18 { 19 LL x; 20 LL y; 21 LL id; 22 LL cou; 23 } sd; 24 LL M,N; 25 ss cnt[100005]; 26 int flag[4*100005]; 27 sd tree[4*100005]; 28 using namespace std; 29 int main(void) 30 { 31 LL n,i,j,k,p,q; 32 scanf("%lld",&n); 33 for(i=1; i<=n; i++) 34 { 35 scanf("%lld %lld",&N,&M); 36 memset(tree,0,sizeof(tree)); 37 for(j=1; j<=N; j++) 38 { 39 scanf("%lld %lld",&cnt[j].x,&cnt[j].y); 40 cnt[j].id=j; 41 if(cnt[j].x==1) 42 { 43 cnt[j].t=cnt[j].y;//操作1时所要乘的数。 44 } 45 else cnt[j].t=1;//操作2时乘的数等价为1; 46 } 47 build(1,N,0);//建树(因为每步操作都有对应的操作,所以将操作2也放入一起操所,等价为所要乘的数为1) 48 printf("Case #%lld:\n",i); 49 for(j=1; j<=N; j++) 50 { 51 if(cnt[j].x==1) 52 { 53 LL dd=que(1,j,0,1,N);//当1时询问找点 54 printf("%lld\n",dd); 55 } 56 else if(cnt[j].x==2) 57 { 58 up(flag[cnt[j].y],j);//当2时断点更新 59 LL dd=que(1,j,0,1,N);//询问找点 60 printf("%lld\n",dd); 61 } 62 } 63 } 64 return 0; 65 } 66 void build(LL l,LL r,LL k)//建树 67 { 68 tree[k].x=l; 69 tree[k].y=r; 70 if(l==r) 71 { 72 tree[k].cou=cnt[l].t%M; 73 flag[l]=k; 74 return; 75 } 76 else 77 { 78 build(l,(l+r)/2,2*k+1); 79 build((l+r)/2+1,r,2*k+2); 80 tree[k].cou=(tree[2*k+1].cou*tree[2*k+2].cou)%M; 81 } 82 } 83 void up(LL k,LL l)//断点更新 84 { 85 tree[k].cou=1;//要删除的点处就相当于乘 86 k=(k-1)/2; 87 while(k>=0)//向上更新到根结点 88 { 89 tree[k].cou=(tree[2*k+1].cou*tree[2*k+2].cou)%M; 90 if(k==0) 91 { 92 break; 93 } 94 k=(k-1)/2; 95 } 96 } 97 LL que(LL l,LL r,LL k,LL aa,LL dd)//询问 98 { 99 if(l>dd||r<aa) 100 { 101 return 1; 102 } 103 else if(l<=aa&&r>=dd) 104 { 105 return tree[k].cou; 106 } 107 else 108 { 109 LL nx=que(l,r,2*k+1,aa,(aa+dd)/2); 110 LL ny=que(l,r,2*k+2,(aa+dd)/2+1,dd); 111 return (nx*ny)%M; 112 } 113 114 }
时间: 2024-10-10 09:41:33