1e5次操作,op = 1,就乘上一个数y(1e9) ,op = 2,就除以第n次乘上的数。求每次操作后对m取余的值。
居然是线段树。
//线段树 1e5确实看起来像
#include <iostream>
#include <cstdio>
using namespace std;
#define mid (l + r) / 2
#define lc rt << 1
#define rc rt << 1 | 1
const int maxn = 1e5 + 5;
typedef long long ll;
int seg[maxn << 2];
int q,m,op,ty,n;
void init(int l,int r,int rt)
{
if(l == r){
seg[rt] = 1;
return;
}
init(l, mid, lc);
init(mid + 1, r, rc);
seg[rt] = (ll)seg[lc] * seg[rc] % m;
}
ll query(int ql,int qr,int l,int r,int rt)
{
if(qr < ql) return 1;
if(ql <= l && r <= qr) return seg[rt];
ll ans = 1;
if(ql <= mid) ans = query(ql,qr,l, mid, lc);
if(mid < qr) ans = ans * query(ql,qr,mid + 1, r, rc) % m;
return ans;
}
void update(int l,int r,int rt,int pos,int val)
{
if(l == r){
seg[rt] = val;
return;
}
if(pos <= mid) update(l,mid,lc,pos,val);
else update(mid + 1, r, rc, pos, val);
seg[rt] = (ll)seg[lc] * seg[rc] % m;
}
int main()
{
int T;cin >> T;
for (int cn = 1; cn <= T; cn ++) {
scanf("%d%d",&q,&m);
init(1, q, 1);
printf("Case #%d:\n",cn);
for (int i = 1; i <= q; i ++) {
scanf("%d",&op);
if(op == 1){
scanf("%d",&ty);
update(1, q, 1, i, ty);
}
else {
scanf("%d",&n);
update(1, q, 1, n, 1);
}
printf("%d\n",(seg[1] + m) % m);
}
}
return 0;
}