育碧荷蘭澄清Ubisoft+服務加入XGP:暫時僅登入Xbox主機
阿新 • • 發佈:2022-05-03
分析
太有意思哇,巧妙的很哇。
初一看這個題,覺得這麼簡單?
然後發現直接模擬肯定不行啊,直接模擬G了,因為mod的數不是個質數,也沒辦法很好的直接算。
看了題解,太妙了。
解法
我們按照時間軸建樹。初始時每個葉節點都賦1,最後維護區間乘的結果。
對於兩個操作
-
x*m
,則我們在第i
個位置插入m -
x/第pos個操作的數
,則將pos
位置置為1
則直接查tr[1]
即為答案,巧妙啊。
直接看看程式碼。
Ac_code
#include<bits/stdc++.h> using namespace std; const int N = 1e5 + 10; struct Node { int l,r,sum; }tr[N<<2]; int n,m; void pushup(int u) { tr[u].sum = 1ll*tr[u<<1].sum*tr[u<<1|1].sum%m; } void build(int u,int l,int r) { if(l==r) { tr[u] = {l,r,1}; return ; } tr[u] = {l,r}; int mid = l + r >> 1; build(u<<1,l,mid),build(u<<1|1,mid+1,r); pushup(u); } void modify(int u,int x,int k) { if(tr[u].l==tr[u].r) { tr[u].sum = k; return ; } int mid = tr[u].l + tr[u].r >> 1; if(x<=mid) modify(u<<1,x,k); else modify(u<<1|1,x,k); pushup(u); } int main() { int T;scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); build(1,1,n); for(int i=1;i<=n;i++) { int op,t;scanf("%d%d",&op,&t); if(op==1) modify(1,i,t); else modify(1,t,1); printf("%d\n",tr[1].sum); } } return 0; }