zoukankan      html  css  js  c++  java
  • BZOJ 3196 Tyvj 1730 二逼平衡树 树套树 线段树 treap

    http://www.lydsy.com/JudgeOnline/problem.php?id=3196

    http://hzwer.com/2734.html

    线段树套treap,似乎splay也可以但是抄的hzwer学长的代码。。就写了treap,算是比较需要注意细节的题。需要注意的地方都在注释里。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<cmath>
      6 #include<cstdlib>
      7 #include<cctype>
      8 using namespace std;
      9 #define lc 2*x
     10 #define rc 2*x+1
     11 const int maxn=50010;
     12 const int inf=100000000;
     13 int n,m;
     14 int root[maxn*4];
     15 struct tre{
     16     int v,ls,rs,w;
     17     int rd,siz;
     18 }t[maxn*40];
     19 struct seg{
     20     int l,r,mid;
     21 }e[maxn*4];
     22 int a[maxn]={},tot=0,ans;
     23 int read(){
     24     int x=0,f=1;char ch=getchar();
     25     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
     26     while(isdigit(ch)){x*=10;x+=ch-'0';ch=getchar();}
     27     return x*f;
     28 }
     29 inline void update(int x){t[x].siz=t[t[x].ls].siz+t[t[x].rs].siz+t[x].w;}
     30 inline void rturn(int &x){//左儿子成为根
     31     int y=t[x].ls;
     32     t[x].ls=t[y].rs; t[y].rs=x;
     33     update(x); x=y; 
     34 }
     35 inline void lturn(int &x){//右儿子成为根
     36     int y=t[x].rs;
     37     t[x].rs=t[y].ls; t[y].ls=x;
     38     update(x); x=y; 
     39 }
     40 void insert(int &x,int v){//把一个值放进去
     41     if(!x){x=++tot;t[x].siz=t[x].w=1;t[x].v=v;t[x].rd=rand();return;}
     42     t[x].siz++;
     43     if(t[x].v==v)t[x].w++;
     44     else if(v<t[x].v){ insert(t[x].ls,v);if(t[x].rd>t[t[x].ls].rd)rturn(x);}
     45     else {insert(t[x].rs,v);if(t[x].rd>t[t[x].rs].rd)lturn(x);}
     46     update(x);
     47 }
     48 void del(int &x,int v){//把一个值去掉
     49     if(t[x].v==v){
     50         if(t[x].w>1){t[x].w--;t[x].siz--;return;}
     51         if(t[x].ls*t[x].rs==0)x=t[x].ls+t[x].rs;//使该位置成为其儿子
     52         else if(t[t[x].ls].rd<t[t[x].rs].rd){rturn(x);del(t[x].rs,v);}
     53         //我觉得此时delx是没有必要的可以直接delx的儿子,标注出来如果ac不了再改回去。
     54         else {lturn(x);del(t[x].ls,v);}
     55     }
     56     else if(v<t[x].v)del(t[x].ls,v);
     57     else del(t[x].rs,v);
     58     update(x);
     59 }
     60 void build(int x,int l,int r){//线段树结构
     61     for(int i=l;i<=r;i++)insert(root[x],a[i]);
     62     e[x].l=l;e[x].r=r;
     63     if(l==r)return;
     64     int mid=(l+r)/2;e[x].mid=mid;
     65     build(lc,l,mid);
     66     build(rc,mid+1,r);
     67 }
     68 int getrank2(int x,int v){
     69     if(!x)return 0;
     70     if(t[x].v==v)return t[t[x].ls].siz;
     71     else if(t[x].v>v)return getrank2(t[x].ls,v);
     72     else return t[t[x].ls].siz+t[x].w+getrank2(t[x].rs,v);
     73 }
     74 int getrank(int x,int l,int r,int v){//线段树结构
     75     if(l<=e[x].l&&r>=e[x].r){
     76         return getrank2(root[x],v);
     77     }int pai=0;
     78     if(l<=e[x].mid)pai+=getrank(lc,l,r,v);
     79     if(e[x].mid<r)pai+=getrank(rc,l,r,v);
     80     return pai;
     81 }
     82 void getnum(int x,int y,int k){//二分
     83     int l=0,r=inf,cnt=0;
     84     while(l<=r){//注意二分答案的储存方法,如何避免取到不存在的值
     85         int mid=(l+r)/2;
     86         int w=getrank(1,x,y,mid)+1;
     87         if(w<=k){l=mid+1;cnt=mid;}
     88         else r=mid-1;
     89     }printf("%d
    ",cnt);
     90 }
     91 void change(int x,int z,int v){//线段树结构
     92     del(root[x],a[z]);
     93     insert(root[x],v);
     94     if(e[x].l==e[x].r)return;
     95     if(z<=e[x].mid)change(lc,z,v);
     96     else change(rc,z,v);
     97 }
     98 void befo(int x,int num){
     99     if(!x)return;
    100     if(t[x].v<num){ans=max(t[x].v,ans);befo(t[x].rs,num);}
    101     else befo(t[x].ls,num);
    102 }
    103 void afte(int x,int num){
    104     if(!x)return;
    105     if(t[x].v>num){ans=min(t[x].v,ans);afte(t[x].ls,num);}
    106     else afte(t[x].rs,num);
    107 }
    108 void fir(int x,int l,int r,int num){//线段树结构
    109     if(l<=e[x].l&&e[x].r<=r){
    110         befo(root[x],num);
    111         return;
    112     }
    113     if(l<=e[x].mid)fir(lc,l,r,num);
    114     if(e[x].mid<r)fir(rc,l,r,num);
    115 }
    116 void las(int x,int l,int r,int num){//线段树结构
    117     if(l<=e[x].l&&e[x].r<=r){
    118         afte(root[x],num);
    119         return;
    120     }
    121     if(l<=e[x].mid)las(lc,l,r,num);
    122     if(e[x].mid<r)las(rc,l,r,num);
    123 }
    124 int main(){
    125     //freopen("wtf.in","r",stdin);
    126     n=read();m=read();
    127     for(int i=1;i<=n;i++)a[i]=read();
    128     build(1,1,n);int x,y,z,f;
    129     for(int i=1;i<=m;i++){
    130         scanf("%d",&f);
    131         if(f==1){scanf("%d%d%d",&x,&y,&z);printf("%d
    ",getrank(1,x,y,z)+1);}
    132         else if(f==2){scanf("%d%d%d",&x,&y,&z);getnum(x,y,z);}
    133         else if(f==3){scanf("%d%d",&x,&y);change(1,x,y);a[x]=y;}//记得把数组也改了。。一直re,大概因为这样导致del出现不存在的数无限递归
    134         else if(f==4){scanf("%d%d%d",&x,&y,&z);ans=0;fir(1,x,y,z);printf("%d
    ",ans);}
    135         else{scanf("%d%d%d",&x,&y,&z);ans=inf;las(1,x,y,z);printf("%d
    ",ans);}
    136     }
    137     return 0;
    138 }
    View Code

  • 相关阅读:
    每位设计师都应该拥有的50个CSS代码片段-1
    JS OO库的选择
    Dean Edwards -- Base.js(译)
    Jquery中find、filter等几种用法的差异
    深入Java虚拟机读书笔记第三章安全
    深入Java虚拟机读书笔记第二章平台无关性
    深入Java虚拟机读书笔记第一章Java体系结构介绍
    ThinkInJava4读书笔记之第七章隐藏实施过程
    Java反射机制(转载)
    linux常用svn命令(转载)
  • 原文地址:https://www.cnblogs.com/137shoebills/p/8366370.html
Copyright © 2011-2022 走看看