洛谷传送门
BZOJ传送门
解析:
首先想到的是逆元,然而题目并没有说 m o d mod mod是质数。
那么怎么办?
好像是 O ( n l o g n ) O(nlogn) O(nlogn)复杂度的数据范围。而且每个 1 1 1操作只会被撤销一次。。
线段树!
线段树每次1操作就修改对应叶子节点的值,同时节点维护区间乘积 % m o d \%mod %mod的结果。而2操作就把对应的操作1的叶子节点的权值改成1就行了,同时2操作不动自己操作对应的根节点。初始化所有节点的权值为1。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const
inline int getint(){
re int num;
re char c;
while(!isdigit(c=gc()));num=c^48;
while(isdigit(c=gc()))num=(num<<1)+(num<<3)+(c^48);
return num;
}
inline void outint(int a){
static char ch[13];
if(a<10)return (void)pc(a^48);
while(a)ch[++ch[0]]=a-a/10*10,a/=10;
while(ch[0])pc(ch[ch[0]--]^48);
}
cs int N=100005;
int mod;
int mul[N<<2];
void build(int k,int l,int r){
mul[k]=1;
if(l==r)return ;
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
}
void modify(int k,int l,int r,cs int &pos,cs int &val){
if(l==r){
mul[k]=val%mod;
return;
}
int mid=(l+r)>>1;
if(pos<=mid)modify(k<<1,l,mid,pos,val);
else modify(k<<1|1,mid+1,r,pos,val);
mul[k]=1ll*mul[k<<1]*mul[k<<1|1]%mod;
}
int T,Q;
signed main(){
T=getint();
while(T--){
Q=getint();mod=getint();
build(1,1,Q);
for(int re i=1;i<=Q;++i){
int op=getint();
int val=getint();
switch(op){
case 1:{
modify(1,1,Q,i,val);
outint(mul[1]);pc('\n');
break;
}
case 2:{
modify(1,1,Q,val,1);
outint(mul[1]);pc('\n');
break;
}
}
}
}
return 0;
}