思路分析:其实刚看到这道题的时候我想也没想直接写了一个暴力出来,没有去注意数据范围,结果1分也没得。。。看了数据范围后,我们发现会爆longlong,于是我们考虑进行优化。我们知道,操作1是将上一步得到的一个数乘另外一个数,我们就可以开一个数组,记录相应步骤时输入的值,维护总乘积,若为操作2,则将数组内相应的位置进行更新,并更新乘积,这是什么?单点修改区间查询。于是我们选用线段树进行优化。每次要求输出时输出线段树根节点的值就行了,反正问的是总乘积。
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N=5e6+10; 6 #define int long long //偷懒写法,但可能会跑的很慢. 7 int n,Mod; 8 struct Tree{ 9 int lson,rson,val; 10 }tree[N]; 11 void build(int l,int r,int t){ //初始化 12 tree[t].lson=l;tree[t].rson=r; 13 if(l==r){ 14 tree[t].val=1; 15 return; 16 } 17 int mid=(l+r)>>1; 18 build(l,mid,t<<1); 19 build(mid+1,r,t<<1|1); 20 tree[t].val=tree[t<<1].val*tree[t<<1|1].val%Mod; 21 } 22 void update(int p,int l,int r,int t,int x){ //单点修改 23 if(l==r){ 24 tree[p].val=x%Mod; 25 return; 26 } 27 int mid=(l+r)>>1; 28 if(t<=mid) update(p<<1,l,mid,t,x); 29 else update(p<<1|1,mid+1,r,t,x); 30 tree[p].val=(tree[p<<1].val*tree[p<<1|1].val)%Mod; 31 } 32 signed main(){ 33 //freopen("a.txt","r",stdin); 34 int T; 35 scanf("%lld",&T); 36 while(T--){ 37 scanf("%lld%lld",&n,&Mod); 38 build(1,n,1); 39 for(int i=1;i<=n;++i){ 40 int x,t; 41 scanf("%lld%lld",&t,&x); 42 if(t==1){ //依据情况更新 43 update(1,1,n,i,x); 44 printf("%lld ",tree[1].val); 45 } 46 else{ 47 update(1,1,n,x,1); 48 printf("%lld ",tree[1].val); 49 } 50 } 51 } 52 return 0; 53 }