线段树 刷题记录

BZOJ5334: [Tjoi2018]数学计算

  • 不是很裸的线段树,想不到的童鞋看到题解估计会被气死。。。
  • 线段树维护操作
  • 因为是前缀的乘积所以考虑了一下树状数组,但是有个除余。。所以还是线段树吧
  • 代码:
     1 #include <bits/stdc++.h>
     2 #define nmax 100010
     3 #define tn t[node]
     4 #define sl (node<<1)
     5 #define sr ((node<<1)|1)
     6  
     7 using namespace std;
     8 typedef long long ll;
     9 struct segt{
    10     int l,r;
    11     ll v;
    12 }t[nmax*4];
    13 ll mod,n;
    14  
    15 void build(int l,int r,int node){
    16     tn.v=1;
    17     tn.l=l;
    18     tn.r=r;
    19     if(l==r) return;
    20     int mid=(l+r)>>1;
    21     build(l,mid,sl);
    22     build(mid+1,r,sr);
    23 }
    24  
    25 void upd(int node,int p,ll x){
    26     if(tn.l==tn.r){
    27         tn.v=x;
    28         return;
    29     }
    30     int mid=(tn.l+tn.r)>>1;
    31     if(p<=mid) upd(sl,p,x);
    32     else upd(sr,p,x);
    33     tn.v = (t[sl].v*t[sr].v) % mod;
    34 }
    35  
    36 ll solve(int l,int r,int node){
    37     if(tn.l>=l&&tn.r<=r) return tn.v;
    38     int mid=(tn.l+tn.r)>>1;
    39     ll ans=1;
    40     if(l<=mid) ans = ( ans * solve(l,r,sl) )%mod;
    41     if(r>mid) ans = ( ans * solve(l,r,sr) )%mod;
    42     return ans;
    43 }
    44  
    45 int main(){
    46     int t,op;
    47     ll num;
    48     cin>>t;
    49     while(t--){
    50         scanf("%d%d",&n,&mod);
    51         build(1,n,1);
    52         for (int i=1; i<=n; i++) {
    53             scanf("%d%lld",&op,&num);
    54             if(op==1) upd(1,i,num); else upd(1,num,1);
    55             printf("%lld\n",solve(1,i,1));
    56         }
    57     }
    58     return 0;
    59 }
    _φ(❐_❐✧

猜你喜欢

转载自www.cnblogs.com/jiecaoer/p/11505590.html