首先看题目

因为要取模的原因,所以不能直接用除法,然后如果用逆元的话又发现模不是质数,所以不能用。
然后就是线段树
#define ll long long
#define lc p<<1
#define rc p<<1|1
using namespace std;
const int N=1e5+5;
struct node{
int l;
int r;
ll ji;
}tree[N<<2];
int mod;
void pushup(int p){
tree[p].ji=(tree[lc].ji*tree[rc].ji)%mod;
}
void build(ll p,ll l,ll r){
tree[p]={l,r,1};
if(l==r){
return;
}
int mid=(l+r)>>1;
build(lc,l,mid);
build(rc,mid+1,r);
pushup(p);
}
void change(int p,int x,int c){
if(x==tree[p].l&&x==tree[p].r){
tree[p].ji=c%mod;
return;
}
int mid=(tree[p].l+tree[p].r)>>1;
if(x<=mid)change(lc,x,c);
if(x>mid)change(rc,x,c);
pushup(p);
}
int main(){
int t;
cin>>t;
while(t--){
int q;
cin>>q>>mod;
build(1,1,q);
for(int i=1;i<=q;i++){
int op;
cin>>op;
if(op==1){
int m;
cin>>m;
change(1,i,m);
}
else {
int pos;
cin>>pos;
change(1,pos,1);
}
cout<<tree[1].ji<<endl;
}
}
return 0;
}````
我们先把每一个询问都弄成一个线段树节点,都将值设为1,然后如果第i次操作是操作一,就相当于把第i节点的值改为m,就是1乘m。如果是操作二,就相当于把第pos节点的值改为1,
因为我们最后是去维护前缀积,就是把每一个节点的值相乘,所以除以原来的一个数,就相当于把这个位置的值改为1.