[TJOI2018]数学计算

[TJOI2018]数学计算

思路一:直接模拟(会因为爆 l o n g   l o n g long\ long long long的问题导致代码非常复杂)

思路二:考虑线段树。建立一棵线段树,其叶子节点都是对应的乘数,每个非叶子节点的值为其左右儿子的值的乘积对 mod \text{mod} mod 取模的值。这样,任意时候都有 x = x= x=该线段树的根的值。操作 1 1 1可以直接上,操作 2 2 2可以看做是把第 t t t次的乘数改为 1 1 1。然后考虑使用线段树分治的思想处理即可。

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=100000+50;
inline int read(){
	int cnt=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-f;c=getchar();}
	while(isdigit(c)){cnt=(cnt<<3)+(cnt<<1)+(c^48);c=getchar();}
	return cnt*f;
}
struct tree{int val;}tr[N<<2];
int q,mod,t,op,m;
inline void pushup(int p){tr[p].val=(tr[p<<1].val%mod*tr[p<<1|1].val%mod)%mod;}
void build(int p,int l,int r){
	if(l==r) {tr[p].val=1;return;}
	int mid=(l+r)>>1;
	build(p<<1,l,mid);
	build(p<<1|1,mid+1,r);
	pushup(p);
	return;
}
void modify(int p,int l,int r,int x,int v){
	if(l==r) {tr[p].val=v;return;}
	int mid=(l+r)>>1;
	if(x<=mid) modify(p<<1,l,mid,x,v);
	else modify(p<<1|1,mid+1,r,x,v);
	pushup(p);return;
}
signed main(){
	t=read();
	while(t--){
		q=read(),mod=read();build(1,1,q);
		for(int i=1;i<=q;++i){
			op=read();m=read();
			if(op==1) modify(1,1,q,i,m),printf("%lld\n",tr[1].val);
			else modify(1,1,q,m,1),printf("%lld\n",tr[1].val);
		}
	}
	return 0;
}

©️2020 CSDN 皮肤主题: 我行我“速” 设计师:Amelia_0503 返回首页