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;
}