[TJOI2018]数学计算
维护除法的取余需要逆元,显然这题数据量不支持这么做
考虑维护一个数据结构,除法改为:x变成1
这样所有数字的乘积就是现在的答案
线段树维护区间乘积+单点修改即可
#include <iostream>
using namespace std;
#define MAXN 100005
int Q,M;
struct Segment_Tree {
long long seg[MAXN<<2];
#define lson (rt<<1)
#define rson (rt<<1|1)
inline void pushup(int rt) {
seg[rt] = seg[lson] * seg[rson] % M;
}
void Build(int rt,int l,int r) {
if(l==r) {
seg[rt] = 1;
return;
}
int mid = (l+r) >> 1;
Build(lson,l,mid);
Build(rson,mid+1,r);
pushup(rt);
}
void update(long long C,int L,int rt,int l,int r) {
if(l==r) {
seg[rt] = C;
return;
}
int mid = (l+r) >> 1;
if(L<=mid) update(C,L,lson,l,mid);
if(L>mid) update(C,L,rson,mid+1,r);
pushup(rt);
}
long long query(int L,int R,int rt,int l,int r) {
if(L>r||R<l) return 1;
if(L<=l&&R>=r) return seg[rt];
int mid = (l+r) >> 1; long long ans = 1;
if(L<=mid) ans = ans*query(L,R,lson,l,mid)%M;
if(R>mid) ans = ans*query(L,R,rson,mid+1,r)%M;
pushup(rt);
return ans;
}
} tr;
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int T; cin >> T;
while(T--) {
cin >> Q >> M;
tr.Build(1,1,Q);
for(int i=1;i<=Q;++i) {
int op; long long x;
cin >> op >> x;
if(op==1) {
tr.update(x,i,1,1,Q);
cout << tr.query(1,Q,1,1,Q) << '\n';
}
else {
tr.update(1,x,1,1,Q);
cout << tr.query(1,Q,1,1,Q) << '\n';
}
}
}
return 0;
}