洛谷 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;
}
posted @ 2021-09-15 11:42  尹昱钦  阅读(41)  评论(0编辑  收藏  举报