• 解题:UOJ #46 玄学


    题面

    二进制分组,修改把区间拆开丢在后面,合并的时候归并最后两块;查询在对应节点上二分答案

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 const int N=100005,Max=1e5;
     6 struct a{int p,k,b;}ope[N*32];
     7 int seq[4*N],lef[4*N],rig[4*N];
     8 int n,T,t1,t2,t3,t4,op,ans,cnt,tot,mod,oni;
     9 void Change(int nde,int l,int r,int ll,int rr,int k,int b)
    10 {
    11     if(l==r)
    12     {
    13         lef[nde]=cnt+1;
    14         if(ll>1) ope[++cnt]=(a){ll-1,1,0};
    15         ope[++cnt]={rr,k,b};
    16         if(rr<n) ope[++cnt]=(a){n,1,0};
    17         rig[nde]=cnt;
    18     } 
    19     else
    20     {
    21         int mid=(l+r)>>1,ls=2*nde,rs=2*nde+1,l1,l2,r1,r2;
    22         if(tot<=mid) Change(ls,l,mid,ll,rr,k,b);
    23         else Change(rs,mid+1,r,ll,rr,k,b);
    24         if(tot>=r)
    25         {
    26               lef[nde]=cnt+1,l1=lef[ls],l2=lef[rs],r1=rig[ls],r2=rig[rs];
    27               while(l1<=r1&&l2<=r2)
    28               {
    29                   ope[++cnt]=(a){min(ope[l1].p,ope[l2].p),
    30                                  1ll*ope[l1].k*ope[l2].k%mod,
    31                                (1ll*ope[l2].k*ope[l1].b+ope[l2].b)%mod};
    32                 if(ope[l1].p==ope[l2].p) l1++,l2++;
    33                 else ope[l1].p<ope[l2].p?l1++:l2++;
    34             }
    35             rig[nde]=cnt;
    36         }
    37     }
    38 }
    39 void Calc(int nde,int tsk)
    40 {
    41     int l=lef[nde],r=rig[nde],p=0;
    42     while(l<=r)
    43     {
    44         int mid=(l+r)>>1;
    45         if(ope[mid].p>=tsk) p=mid,r=mid-1;
    46         else l=mid+1;
    47     }
    48     ans=(1ll*ans*ope[p].k+ope[p].b)%mod;
    49 }
    50 void Query(int nde,int l,int r,int ll,int rr,int tsk)
    51 {
    52     if(l>rr||r<ll)
    53         return ;
    54     else if(l>=ll&&r<=rr)
    55         Calc(nde,tsk);
    56     else
    57     {
    58         int mid=(l+r)>>1,ls=2*nde,rs=2*nde+1;
    59         Query(ls,l,mid,ll,rr,tsk),Query(rs,mid+1,r,ll,rr,tsk);
    60     }
    61 }
    62 int main()
    63 {
    64     scanf("%d",&oni),oni&=1;
    65     scanf("%d%d",&n,&mod);
    66     for(int i=1;i<=n;i++)
    67         scanf("%d",&seq[i]);
    68     scanf("%d",&T);
    69     while(T--)
    70     {
    71         scanf("%d",&op);
    72         if(op==1)
    73         {
    74             scanf("%d%d%d%d",&t1,&t2,&t3,&t4);
    75             t1^=ans*oni,t2^=ans*oni,tot++;
    76             Change(1,1,Max,t1,t2,t3,t4);
    77         }
    78         else
    79         {
    80             scanf("%d%d%d",&t1,&t2,&t3);
    81             t1^=ans*oni,t2^=ans*oni,t3^=ans*oni;
    82             ans=seq[t3],Query(1,1,Max,t1,t2,t3);
    83             printf("%d
    ",ans);
    84         }
    85     }
    86     return 0;
    87 }
    View Code
  • 相关阅读:
    认识计算机
    Sum 类型题目总结
    3Sum Smaller 解答
    3Sum Closest 解答
    Roman to Integer && Integer to Roman 解答
    Longest Common Prefix 解答
    Shortest Word Distance 解答
    Longest Valid Parentheses 解答
    Lowest Common Ancestor of a Binary Search Tree 解答
    Longest Palindromic Substring 解答
  • 原文地址:https://www.cnblogs.com/ydnhaha/p/10513296.html
Copyright © 2020-2023  润新知