seasongirl 2020-05-26
题意很清楚,首先不要没有头绪,我们想一想如果是区间乘%一个数怎么做?直接线段树,然后再看本题,搞一个数组,如果是操作1,对应的数字就是val,操作2对应的就是1,然后对于操作1,就是求1到i的乘积,对于2,直接求1到val-1和val+1到i的乘积.解决问题.
代码:
#include <cstdio> #define ll long long const int maxn=1e5+10; ll mod; struct TREE{ ll val; int l; int r; ll lazyp; ll lazym; }tr[maxn*4]; void build(int x,int l,int r){ tr[x].l=l; tr[x].r=r; tr[x].lazym=1; tr[x].lazyp=0; if(l==r){ tr[x].val=1; return; } int mid=(l+r)/2; build(x*2,l,mid); build(x*2+1,mid+1,r); tr[x].val=(tr[x*2].val*tr[x*2+1].val)%mod; } ll cha(int x,int l,int r){ if(tr[x].l>=l&&tr[x].r<=r) return tr[x].val; int mid=(tr[x].l+tr[x].r)/2; ll ans=1; if(l<=mid) ans*=cha(x*2,l,r); ans%=mod; if(r>=mid+1) ans*=cha(x*2+1,l,r); ans%=mod; return ans; } void chan(int x,int s,ll ke){ if(tr[x].l==tr[x].r){ tr[x].val=ke; return; } int mid=(tr[x].l+tr[x].r)/2; if(s<=mid) chan(x*2,s,ke); if(s>=mid+1) chan(x*2+1,s,ke); tr[x].val=tr[x*2].val*tr[x*2+1].val%mod; } int w[maxn]; ll val[maxn]; int main(){ int t; scanf("%d",&t); for(int jsjs=1;jsjs<=t;jsjs++){ int q; scanf("%d%lld",&q,&mod); build(1,1,q); for(int i=1;i<=q;i++){ scanf("%d%d",&w[i],&val[i]); if(w[i]==1) chan(1,i,val[i]); else chan(1,val[i],1); printf("%lld\n",cha(1,1,i)%mod); } } return 0; }