小豆现在有一个数x,初始值为1. 小豆有Q次操作,操作有两种类型:
1 m: x = x * m ,输出 x%mod;
2 pos: x = x / 第pos次操作所乘的数(保证第pos次操作一定为类型1,对于每一个类型1 的操作至多会被除一次),输出x%mod
一共有t组输入(t ≤ 5)
对于每一组输入,第一行是两个数字Q, mod(Q ≤ 100000, mod ≤ 1000000000);
接下来Q行,每一行为操作类型op,操作编号或所乘的数字m(保证所有的输入都是合法的).
1 ≤ Q ≤ 100000
———————————————
——————————
如何解决:
考虑用线段树,操作一就在操作的位置插入m,操作二就是把第pos位贡献变为1,这样求区间乘积就可以了
——————————————————————————————————
——————————————
代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define ll long long
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
const int maxn=200005;
int treee[maxn<<2],mod;
int read(){
int x=0,v=1; char ch=getchar();
for (;ch<'0'||ch>'9';v=(ch=='-')?(-1):(v),ch=getchar());
for (;ch<='9'&&ch>='0';x=x*10+ch-'0',ch=getchar());
return x*v;
}
void modify(int now,int tl,int tr,int x,int v){
if (tl==tr) return (void) (treee[now]=v);
int mid=(tl+tr)>>1;
if (x<=mid) modify(now<<1,tl,mid,x,v);
else modify(now<<1|1,mid+1,tr,x,v);
treee[now]=1LL*treee[now<<1]*treee[now<<1|1]%mod;
}
int query(int now,int tl,int tr,int l,int r) {
if (r<l) return 1;
if (tl>=l&&tr<=r) return treee[now];
int mid=(tl+tr)>>1;
int qx=query(now<<1,tl,mid,l,std:: min(r,mid));
int qy=query(now<<1|1,mid+1,tr,std:: max(mid+1,l),r);
return 1LL*qx*qy%mod;
}
void build(int now,int tl,int tr) {
treee[now]=1;
if (tl==tr) return ;
int mid=(tl+tr)>>1;
build(now<<1,tl,mid);
build(now<<1|1,mid+1,tr);
}
int main(){
//freopen("a.in","r",stdin);
for (int T=read();T--;) {
int n=read(); mod=read();
build(1,1,n);
rep(i,1,n){
int opt=read(),x=read();
if(opt==1)modify(1,1,n,i,x);
else modify(1,1,n,x,1);
printf("%d\n", treee[1]);
}
}
return 0;
}
代码:
#include <stdio.h> #include <string.h> #include <algorithm> #define ll long long #define rep(i,st,ed) for (int i=st;i<=ed;++i) const int maxn=200005; int treee[maxn<<2],mod; int read(){ int x=0,v=1; char ch=getchar(); for (;ch<'0'||ch>'9';v=(ch=='-')?(-1):(v),ch=getchar()); for (;ch<='9'&&ch>='0';x=x*10+ch-'0',ch=getchar()); return x*v; } void modify(int now,int tl,int tr,int x,int v){ if (tl==tr) return (void) (treee[now]=v); int mid=(tl+tr)>>1; if (x<=mid) modify(now<<1,tl,mid,x,v); else modify(now<<1|1,mid+1,tr,x,v); treee[now]=1LL*treee[now<<1]*treee[now<<1|1]%mod; } int query(int now,int tl,int tr,int l,int r) { if (r<l) return 1; if (tl>=l&&tr<=r) return treee[now]; int mid=(tl+tr)>>1; int qx=query(now<<1,tl,mid,l,std:: min(r,mid)); int qy=query(now<<1|1,mid+1,tr,std:: max(mid+1,l),r); return 1LL*qx*qy%mod; } void build(int now,int tl,int tr) { treee[now]=1; if (tl==tr) return ; int mid=(tl+tr)>>1; build(now<<1,tl,mid); build(now<<1|1,mid+1,tr); } int main(){ //freopen("a.in","r",stdin); for (int T=read();T--;) { int n=read(); mod=read(); build(1,1,n); rep(i,1,n){ int opt=read(),x=read(); if(opt==1)modify(1,1,n,i,x); else modify(1,1,n,x,1); printf("%d\n", treee[1]); } } return 0; }