• UOJ#46. 【清华集训2014】玄学


    传送门

    分析

    清华集训真的不是人做的啊嘤嘤嘤

    我们可以考虑按操作时间把每个操作存进线段树里

    如果现在点x正好使一个整块区间的右端点则更新代表这个区间的点

    我们不难发现一个区间会因为不同的操作被分成若干块,每块对应序列上不同的区间

    于是查询时对于每个线段树上区间查询时二分查找当前点在哪一块中即可

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    #define int long long
    int n,m,a[100100],Q,tot,Ans,cnt,L[3001000],R[3001000];
    struct node {
        int le,ri,a,b;
    };
    node d[30010000];
    inline void PUSH(int wh,int le,int ri,int aa,int bb){
        d[wh].le=le,d[wh].ri=ri,d[wh].a=aa,d[wh].b=bb;
    }
    inline void update(int wh,int le,int ri){
        int i,j,k,be=1;
        L[wh]=cnt+1;
        for(i=L[le],j=L[ri];i<=R[le]&&j<=R[ri];){
          if(d[i].ri>=d[j].ri){
              PUSH(++cnt,be,d[j].ri,d[i].a*d[j].a%m,(d[j].a*d[i].b+d[j].b)%m);
              be=d[j].ri+1;
              if(d[i].ri==d[j].ri)i++;
              j++;
          }else {
              PUSH(++cnt,be,d[i].ri,d[i].a*d[j].a%m,(d[j].a*d[i].b%m+d[j].b)%m);
              be=d[i].ri+1;
              i++;
          }
        }
        R[wh]=cnt;
    }
    inline void build(int le,int ri,int wh,int pl,int x,int y,int k1,int k2){
        if(le==ri){
          L[wh]=cnt+1;
          if(x>1)PUSH(++cnt,1,x-1,1,0);
          PUSH(++cnt,x,y,k1,k2);
          if(y<n)PUSH(++cnt,y+1,n,1,0);
          R[wh]=cnt;
          return;
        }
        int mid=(le+ri)>>1;
        if(mid>=pl)build(le,mid,wh<<1,pl,x,y,k1,k2);
          else build(mid+1,ri,wh<<1|1,pl,x,y,k1,k2);
        if(ri==pl)update(wh,wh<<1,wh<<1|1);
    }
    inline void work(int wh,int pl){
        int le=L[wh],ri=R[wh];
        while(ri-le>0){
          int mid=(le+ri)>>1;
          if(pl<=d[mid].ri)ri=mid; 
            else le=mid+1;
        }
        Ans=(Ans*d[le].a%m+d[le].b)%m;
    }
    inline void q(int le,int ri,int wh,int x,int y,int k){
        if(le>=x&&ri<=y){
          work(wh,k);
          return;
        }
        int mid=(le+ri)>>1;
        if(mid>=x)q(le,mid,wh<<1,x,y,k);
        if(mid<y)q(mid+1,ri,wh<<1|1,x,y,k);
    }
    signed main(){
        int i,j,k,t;
        scanf("%lld",&t);
        scanf("%lld%lld",&n,&m);
        for(i=1;i<=n;i++)scanf("%lld",&a[i]);
        scanf("%lld",&Q);
        for(i=1;i<=Q;i++){
          int le,ri,x,y;
          scanf("%lld%lld%lld",&k,&le,&ri);
          if(t&1)le^=Ans,ri^=Ans;
          if(k==1){
              scanf("%lld%lld",&x,&y);
              tot++;
              build(1,Q,1,tot,le,ri,x,y);
          }else {
              scanf("%lld",&x);
              if(t&1)x^=Ans;
              Ans=a[x];
              q(1,Q,1,le,ri,x);
              printf("%lld
    ",Ans);
          }
        }
        return 0;
    }
  • 相关阅读:
    CSS------制作一个带+-的input框
    rest简介
    flask之flask-login登陆验证(一)
    Python之异常设计(一)
    flask之flask-sqlalchemy(一)
    flask之wtforms 表单验证(一)
    三 Django模型层之Meta
    二 Djano模型层之模型字段选项
    一 Django模型层简介
    Django之路由、模板和模型系统 (转载)
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/10373696.html
Copyright © 2020-2023  润新知