P4588 [TJOI2018] 数学计算

P4588 [TJOI2018] 数学计算

思路:

这次题目很简单,应该都看得懂 QwQ
这道题因为数据很大,要取模,但在操作中要进行除法运算,对一个已经取了模的数进行除法运算会使它不正确,还有可能变为小数。因此不能用普通思路。
但我们发现它每一次除的都是之前乘过的树,换句话说就可以将之前乘的树变为一即可,这时我们就可以构造一线段树,维护每一次操作,做区间乘。若此次操作为乘,就将这次操作对应的节点变为这个数;若此次操作为除,就将第\(pos\)次的树变为一即可,输出就输出根节点。

完整代码:

#include<bits/stdc++.h>
#define lc p<<1
#define rc p<<1|1
#define int long long
using namespace std;
const int N=1e5+5;
int tr[N*4],M;
void update(int p,int l,int r,int num,int q){
	if(l==r){
		tr[p]=q;
		return;
	}
	int mid=(l+r)>>1;
	if(num<=mid)update(lc,l,mid,num,q);
	if(num>mid)update(rc,mid+1,r,num,q);
	tr[p]=(tr[lc]*tr[rc])%M;
}
signed main(){
	int t;
	cin>>t;
	while(t--){
		int q;
		cin>>q>>M;
		for(int i=1;i<=4*q;i++)tr[i]=1;
		for(int i=1;i<=q;i++){
			int op;
			cin>>op;
			if(op==1){
				int m;
				cin>>m;
				update(1,1,q,i,m%M);
				cout<<tr[1]<<endl;
			}
			if(op==2){
				int pos;
				cin>>pos;
				update(1,1,q,pos,1);
				cout<<tr[1]<<endl;
			}
		}
	}
	
}

线段树讲解

posted @ 2025-01-20 18:59  XichenOC  阅读(14)  评论(0)    收藏  举报