傳送門 ←點這裏
題意:
在一個 初始值爲 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;
}