洛谷 P4588 [TJOI2018]数学计算(线段树)
传送门
解题思路
直接算逆元太麻烦。
可以用线段树维护区间乘积。
需要进行单点修改和查询整个区间的乘积。
- 每次1操作,就把当前点修改为m;
- 每次2操作,就把m点修改为1。
AC代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=1e5+5;
int n,m,t,op,x;
long long d[maxn*4],mod;
inline void pushup(int id){
d[id]=d[id*2]*d[id*2+1]%mod;
}
void build(int id,int l,int r){
d[id]=1;
if(l==r) return;
int mid=(l+r)/2;
build(id*2,l,mid);
build(id*2+1,mid+1,r);
}
void update(int id,int l,int r,int x,long long v){
if(l==r){
d[id]=v%mod;
return;
}
int mid=(l+r)/2;
if(x<=mid) update(id*2,l,mid,x,v);
else update(id*2+1,mid+1,r,x,v);
pushup(id);
}
int main(){
cin>>t;
while(t--){
memset(d,0,sizeof(d));
cin>>n>>mod;
build(1,1,n);
for(int i=1;i<=n;i++){
cin>>op>>x;
if(op==1) update(1,1,n,i,x%mod);
else update(1,1,n,x,1);
cout<<d[1]%mod<<endl;
}
}
return 0;
}