zoukankan      html  css  js  c++  java
  • BZOJ2770: YY的Treap

    原本看标题还以为是treap的题,但是实际上是线段树。

    求两点的LCA相当于求区间priority最小值的位置。

    然后就可以离线先离散化然后建树做了。

    记录的minpos是线段树上叶子结点的节点编号。

    一道水题。

    题目链接

    //Serene
     #include<algorithm>
     #include<iostream>
     #include<cstring>
     #include<cstdlib>
     #include<cstdio>
     #include<cmath>
     #include<set>
     using namespace std;
     const long long maxn=1e5+10,maxm=3e5+10,INF=1e18;
     long long n,m;
     long long pp[maxn],pr[maxn],rr[maxm],rp[maxm];
     char kk[maxm];
     long long num[maxn+maxm],tot=0;
     
     set<long long> G;
     set<long long>::iterator it;
     
     long long aa,ff;char cc;
     long long read() {
         aa=0;ff=1;cc=getchar();
         while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
         if(cc=='-') ff=-1,cc=getchar();
         while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
         return aa*ff;
     }
     
     struct Node{
         int l,r,minpos;long long minnum;
     }node[4*(maxn+maxm)];
     
     void bld(int pos,int l,int r) {
         node[pos].l=l;node[pos].r=r;
         node[pos].minnum=INF;
         if(l==r) {
             node[pos].minpos=pos;
             return;
         }
         int mid=(l+r)>>1;
         bld(pos<<1,l,mid);
         bld(pos<<1|1,mid+1,r);
         node[pos].minpos=node[pos<<1].minpos;
     }
     
     void chge(int pos,int os,long long prr) {
         if(node[pos].l==node[pos].r) {
             node[pos].minnum=prr;
             node[pos].minpos=pos;
             return ;
         }
         int mid=(node[pos].l+node[pos].r)>>1;
         if(os<=mid) chge(pos<<1,os,prr);
         else chge(pos<<1|1,os,prr);
         node[pos].minnum=min(node[pos<<1].minnum,node[pos<<1|1].minnum);
         node[pos].minpos= node[pos<<1].minnum<node[pos<<1|1].minnum? node[pos<<1].minpos:node[pos<<1|1].minpos;
     }
     
     int ef(int l,int r,long long key) {
         if(l>=r-1) return l;
         int mid=(l+r)>>1;
         if(num[mid]==key) return mid;
         if(num[mid]>key) return ef(l,mid,key);
         return ef(mid+1,r,key);
     }
     
     int q(int pos,int l,int r) {
         if(l>r) swap(l,r);
         if(node[pos].l==l&&node[pos].r==r) return node[pos].minpos;
         int mid=(node[pos].l+node[pos].r)>>1;
         if(l>mid) return q(pos<<1|1,l,r);
         if(r<=mid) return q(pos<<1,l,r);
         int ans1=q(pos<<1,l,mid),ans2=q(pos<<1|1,mid+1,r);
         return node[ans1].minnum<node[ans2].minnum? ans1:ans2;
     }
     
     int main() {
         n=read();m=read();
         for(int i=1;i<=n;++i) {
             pp[i]=read();
             G.insert(pp[i]);
         }
         for(int i=1;i<=n;++i) pr[i]=read();
         for(int i=1;i<=m;++i) {
             kk[i]=getchar();
             while(kk[i]<'A'||kk[i]>'Z') kk[i]=getchar();
             rr[i]=read();
             if(kk[i]!='D') rp[i]=read();
             if(kk[i]=='I') G.insert(rr[i]);
         }
         for(it=G.begin();it!=G.end();++it) num[++tot]=*it;
         bld(1,1,tot);
         for(int i=1;i<=n;++i) chge(1,ef(1,tot+1,pp[i]),pr[i]);
         for(int i=1;i<=m;++i) {
             if(kk[i]=='I') chge(1,ef(1,tot+1,rr[i]),rp[i]);
             else if(kk[i]=='D') chge(1,ef(1,tot+1,rr[i]),INF);
             else printf("%lld
    ",num[node[q(1,ef(1,tot+1,rr[i]),ef(1,tot+1,rp[i]))].l]);
         }
         return 0;
    }
    

      

    弱者就是会被欺负呀
  • 相关阅读:
    部分模块
    正则表达式和re模块
    软件开发的目录规范
    模块以及模块的导入
    迭代器、可迭代对象、迭代器对象、生成器、生成器表达式和相关的面试题
    内置方法补充
    递归、二分法、匿名函数和部分内置方法
    python的闭包和装饰器
    函数名本质、函数命名空间和作用域链
    函数简介和函数的结构分析
  • 原文地址:https://www.cnblogs.com/Serene-shixinyi/p/7360302.html
Copyright © 2011-2022 走看看