• 主席树


    单点修改

    procedure makentree(l,r:longint);
      var
       mid,t:longint;
        begin
          inc(cnt);
          tr[cnt].z:=l;tr[cnt].y:=r;
          mid:=(l+r) div 2;
          t:=cnt;
    
          if l=r then exit;
    
          if l<=mid then
            begin
              tr[t].lc:=cnt+1;
              makentree(l,mid);
            end;
          if r>mid then
            begin
              tr[t].rc:=cnt+1;
              makentree(mid+1,r);
            end;
        end;
    
      procedure exptree(po,va:longint);
      var
       mid,t:longint;
        begin
          inc(cnt);
          tr[cnt].z:=tr[fol].z;
          tr[cnt].y:=tr[fol].y;
          tr[cnt].sum:=tr[fol].sum+1;
          mid:=(tr[fol].z+tr[fol].y) div 2;
    
          if tr[fol].z=tr[fol].y then exit;
    
          if va<=mid then
            begin
              tr[cnt].rc:=tr[fol].rc;
              tr[cnt].lc:=cnt+1;
              t:=fol;
              fol:=tr[fol].lc;
              exptree(tr[t].lc,va);
            end;
          if va>mid then
            begin
              tr[cnt].lc:=tr[fol].lc;
              tr[cnt].rc:=cnt+1;
              t:=fol;
              fol:=tr[fol].rc;
              exptree(tr[t].rc,va);
            end;
        end;
    
     cnt:=0;
        makentree(1,m);
        root[0]:=1;
    
        for i:=1 to n do
          begin
            root[i]:=cnt+1;
            fol:=root[i-1];
            exptree(fol,a[rk[i]]);
          end;
     

    区间加减维护max,min(bzoj2653 middle)

    #include<algorithm>
    #include<cstdio>
    
     struct data{
         int key,num;
     }inp[200001];
     
     struct treenode{
         int l,r,lc,rc,mi,ma,toadd,ex;
     }tr[4000000];
    
    int cnt,fol;
    long long res[200001];
    int a[200001],edi[200001],root[200001];
     
      int comp(const data &a,const data &b){
          if (a.key>b.key) return(0);
          if (a.key<b.key)return(1);
          if (a.num<b.num) return(1);
          return(0);
      }
      
      int ma(int a,int b){
          if (a>b) return(a);else return(b);
      }
      
      int mi(int a,int b){
        if (a<b) return(a);else return(b);
      }
      
      void makentree(int left,int right){
          tr[++cnt].l=left;tr[cnt].r=right;
          tr[cnt].toadd=0;
          tr[cnt].ex=0;
          int mid=(left+right)/2;
          if (left==right){
              tr[cnt].ma=left;tr[cnt].mi=left;return;
          }else {
              int t=cnt;
              tr[t].lc=cnt+1;
              makentree(left,mid);
              tr[t].rc=cnt+1;
              makentree(mid+1,right);
              tr[t].ma=ma(tr[tr[t].lc].ma,tr[tr[t].rc].ma);
              tr[t].mi=mi(tr[tr[t].lc].mi,tr[tr[t].rc].mi);
          }
      }
      
      void ex(int fol){
          tr[cnt+1]=tr[tr[fol].lc];
          tr[cnt+2]=tr[tr[fol].rc];
          tr[cnt+1].toadd+=tr[fol].toadd;
        tr[cnt+2].toadd+=tr[fol].toadd;
        tr[cnt+1].ex=1;
        tr[cnt+2].ex=1;
        tr[fol].ma+=tr[fol].toadd;
        tr[fol].mi+=tr[fol].toadd;
        tr[fol].toadd=0;
          tr[fol].lc=cnt+1;
          tr[fol].rc=cnt+2;
          cnt+=2;
          tr[fol].ex=0;
      }
      
      void exptree(int t,int left,int right){
             tr[t].ex=1;
             if (tr[t].l==left&&tr[t].r==right) 
             {tr[t].toadd-=2;
              return;}
             
           if (tr[t].ex) ex(t);
           int mid=(tr[fol].l+tr[fol].r)/2;
           int bckup=fol;
           if (left<=mid){fol=tr[fol].lc;exptree(tr[t].lc,left,mi(mid,right));}
           fol=bckup;
           if (right>mid){fol=tr[fol].rc;exptree(tr[t].rc,ma(left,mid+1),right);}
           tr[t].ma=ma(tr[tr[t].lc].ma+tr[tr[t].lc].toadd,tr[tr[t].rc].ma+tr[tr[t].rc].toadd);
           tr[t].mi=mi(tr[tr[t].lc].mi+tr[tr[t].lc].toadd,tr[tr[t].rc].mi+tr[tr[t].rc].toadd);
        }
            
      
      int getmax(int po,int l, int r){
            if (tr[po].l==l&&tr[po].r==r) return(tr[po].ma+tr[po].toadd);
            if (tr[po].ex) ex(po);
             
            int mid=(tr[po].l+tr[po].r)/2;
          int t=-1000000;
          if (l<=mid) t=ma(getmax(tr[po].lc,l,mi(r,mid)),t);
          if (r>mid)  t=ma(getmax(tr[po].rc,ma(mid+1,l),r),t);
          return(t);
      }
      
      int getmin(int po,int l,int r){
            if (tr[po].l==l&&tr[po].r==r) return(tr[po].mi+tr[po].toadd);
            if (tr[po].ex)ex(po);        
            int mid=(tr[po].l+tr[po].r)/2;
          int t=1000000;
          if (l==0){
              t=0;l++;
          }
          if (l<=mid) t=mi(getmin(tr[po].lc,l,mi(r,mid)),t);
          if (r>mid)  t=mi(getmin(tr[po].rc,ma(mid+1,l),r),t);
          return(t);
      }
    
      int main(){int n;
          scanf("%d",&n);
          
          for (int i=1;i<=n;i++){
              scanf("%lld",&inp[i].key);
              inp[i].num=i;
          }
          
        std::sort(inp+1,inp+n+1,comp);  
        
        for (int i=1;i<=n;i++){
            res[i]=inp[i].key;
            a[inp[i].num]=i;
            edi[i]=inp[i].num;
        }
        
        root[0]=1;
        makentree(1,n);
        
    
        for (int i=1;i<=n;i++){
            root[i]=++cnt;
            tr[root[i]]=tr[root[i-1]];
            fol=root[i-1];
            exptree(cnt,edi[i],n);    
        };
        
        int last=1;
        for (int i=1;i<=n;i++)
          if (res[i]==res[i-1])
            root[i-1]=root[i-2];
      ++cnt;
        int m;
        int tmp[5];
        scanf("%d",&m);
        long long lasans=0;
        for (int i=1;i<=m;i++){
          for (int j=1;j<=4;j++) {scanf("%d",&tmp[j]);  tmp[j]=((tmp[j]+lasans)%n+n)%n;};
            std::sort(tmp+1,tmp+5);
            int a=tmp[1]+1,b=tmp[2]+1,c=tmp[3]+1,d=tmp[4]+1;
            int l=1;int r=n;
            while (l<r){
                int mid=(l+r+1)/2;
                int t1=getmax(root[mid-1],c,d),
                t2=getmin(root[mid-1],a-1,b-1);
                if (t1-t2>=0) l=mid;
                 else r=mid-1;
            }
            lasans=res[l];
            printf("%lld
    ",lasans);
        }
        
        return(0);
      }
      
      

     ——————————————————————————————————————————————————

    将l,r在递归时维护可以减少占用内存(BZOJ3524)

    #include <cstdio>
    
      int cnt,r,l;
      int root[500001];
    
      struct data{
          int lc,rc,num;
      }tr[16666661];
    
      void build(int l,int r){
          ++cnt;
          if (l==r) return;
          
          int mid=(l+r)>>1,t=cnt;
          tr[t].lc=cnt+1;
          build(l,mid);
          tr[t].rc=cnt+1;
          build(mid+1,r);
      }
      
      void edi(int po,int trpol,int trpor,int tar){
          tr[++cnt]=tr[po];
          tr[cnt].num++;
          if (trpol==trpor) return;
          
          int mid=(trpol+trpor)>>1;
          if (tar<=mid){
            tr[cnt].lc=cnt+1;
          edi(tr[po].lc,trpol,mid,tar);    
        }else{
          tr[cnt].rc=cnt+1;
          edi(tr[po].rc,mid+1,trpor,tar);
        }
      } 
      
      int query(int poa,int pob,int trpol,int trpor,int k){
          if (trpol==trpor){
            int tmp=tr[poa].num-tr[pob].num;
          if (tmp>(r-l+1)/2) return(trpol);else return(0);
        }
            
          int lcnum=tr[tr[poa].lc].num-tr[tr[pob].lc].num,mid=(trpol+trpor)>>1;
        if (lcnum>=k) return(query(tr[poa].lc,tr[pob].lc,trpol,mid,k));
                      return(query(tr[poa].rc,tr[pob].rc,mid+1,trpor,k-lcnum));  
      }
    
      int main(){      
          int n,m;
          scanf("%d%d",&n,&m);
          root[0]=1;
          build(1,n);  
        for (int i=1;i<=n;i++){
          int t;
          scanf("%d",&t);
          root[i]=cnt+1;
          edi(root[i-1],1,n,t);    
        }    
        
        for (int i=1;i<=m;i++){
          scanf("%d%d",&l,&r);
          int ret=query(root[r],root[l-1],1,n,(r-l+2)/2);
          printf("%d
    ",ret);    
        }
      }
  • 相关阅读:
    mingW与cygwin
    Ruby on Rails 和 J2EE:两者能否共存?
    嵌入式Linux学习笔记(一) 启航、计划和内核模块初步体验
    嵌入式Linux学习笔记(六) 上位机QT界面实现和通讯实现
    嵌入式Linux问题总结(一) Ubuntu常用命令和编译问题解决方法
    嵌入式Linux学习笔记(五) 通讯协议制定和下位机代码实现
    嵌入式Linux学习笔记(四) 设备树和UART驱动开发
    嵌入式Linux学习笔记(三) 字符型设备驱动--LED的驱动开发
    嵌入式Linux学习笔记(二) 交叉编译环境和Linux系统编译、下载
    记录嵌入式面试的流程
  • 原文地址:https://www.cnblogs.com/zhujiangning/p/5387835.html
Copyright © 2020-2023  润新知