传送门 ←点这里
题意:
在一个 初始值为 x = 1 的计算器上进行两种操作:
1. 乘以y
2. 除以一个 之前乘过 的数
每次操作之后,输出 计算器上显示的数字%M 的值
思路:
操作只有10^5个 可以视为有10^5个数字,他们的初始值都为1。
每次操作都对其中一个数字进行修改:
1操作, 把当前第i个数字改成y
2操作, 把第y个数字改成1
然后利用线段树的性质,对整个1~n的区间进行维护,每次输出sum[1]的值即可....
(。。。不是正解吧。。。逃》
code:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 100005;
int mod;
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
long long sum[maxn<<2];
void pushup(int rt){
sum[rt] = (sum[rt<<1] * sum[rt<<1|1]) % mod;
}
void build(int l, int r, int rt){
sum[rt] = 1;
if(l == r) return;
int m = (l + r) >> 1;
build(lson);
build(rson);
pushup(rt);
}
void update(int p, long long v, int l, int r, int rt){
if(l == r){
sum[rt] = v % mod;
return;
}
int m = (l + r) >> 1;
if(p <= m) update(p, v, lson);
else update(p, v, rson);
pushup(rt);
}
int main(){
int t;
int cas = 0;
int n, op;
long long y;
scanf("%d",&t);
while(t--){
scanf("%d%I64d",&n, &mod);
build(1, n, 1);
printf("Case #%d:\n", ++cas);
for(int i = 1; i <= n; i++){
scanf("%d%I64d", &op, &y);
if(op == 1)
update(i, y, 1, n, 1);
if(op == 2)
update(y, 1, 1, n, 1);
printf("%I64d\n", sum[1]);
}
}
return 0;
}