zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    amoeba连接mysql--ERROR 2006 (HY000): MySQL server has gone away
    fd最大值和限制
    mysql ab主从复制出错及解决过程
    mysql复制知识整理
    MySQL权限
    客户端用plsql进行中文条件查询时无结果的解决办法
    ORACLE ASH/AWR
    总结:常用的Linux系统监控命令(2)
    讨论几种数据列Column的特性(上)
    Spring核心技术(五)——Spring中Bean的作用域
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/10373696.html
Copyright © 2011-2022 走看看