首先看题目
f51c75546084123bf44e60511ae8161
因为要取模的原因,所以不能直接用除法,然后如果用逆元的话又发现模不是质数,所以不能用。
然后就是线段树

#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.