• bzoj3196 二逼平衡树


    题目链接

    平衡树系列最后一题

    坑啊

    10s时间限制跑了9764ms。。。还是要学一学bit套主席树啦。。。

    经典的线段树套treap。。。至于第一发为什么要TLE(我不会告诉你treap插入的时候忘了旋转 WOC)

    自认为treap写的挺好看的(欢迎来喷)

      1 #include<algorithm>
      2 #include<iostream>
      3 #include<cstdlib>
      4 #include<cstring>
      5 #include<cstdio>
      6 #include<string>
      7 #include<cmath>
      8 #include<ctime>
      9 #include<queue>
     10 #include<stack>
     11 #include<map>
     12 #include<set>
     13 #define rre(i,r,l) for(int i=(r);i>=(l);i--)
     14 #define re(i,l,r) for(int i=(l);i<=(r);i++)
     15 #define Clear(a,b) memset(a,b,sizeof(a))
     16 #define inout(x) printf("%d",(x))
     17 #define douin(x) scanf("%lf",&x)
     18 #define strin(x) scanf("%s",(x))
     19 #define LLin(x) scanf("%lld",&x)
     20 #define op operator
     21 #define CSC main
     22 typedef unsigned long long ULL;
     23 typedef const int cint;
     24 typedef long long LL;
     25 using namespace std;
     26 cint inf=100000000;
     27 void inin(int &ret)
     28 {
     29     ret=0;int f=0;char ch=getchar();
     30     while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();}
     31     while(ch>='0'&&ch<='9')ret*=10,ret+=ch-'0',ch=getchar();
     32     ret=f?-ret:ret;
     33 }
     34 int ch[2000050][2],c[2000050],s[2000050],rr[2000050],w[2000020],ed;
     35 struct segtree
     36 {
     37         int l,r,root;
     38         segtree(){root=0;}
     39         void maintain(int k){if(k)s[k]=c[k]+s[ch[k][0]]+s[ch[k][1]];}
     40         void rotate(int &k,int d)
     41         {
     42             int p=ch[k][d^1];
     43             ch[k][d^1]=ch[p][d];
     44             ch[p][d]=k;s[p]=s[k];
     45             maintain(k),k=p;
     46         }
     47     private:
     48         void add(int &k,const int &x)
     49         {
     50             if(!k)
     51             {
     52                 k=++ed,w[k]=x,rr[k]=rand();s[k]=c[k]=1;ch[k][0]=ch[k][1]=0;
     53                 return ;
     54             }s[k]++;
     55             if(x==w[k]){c[k]++;return ;}
     56             int d=x>w[k];add(ch[k][d],x);
     57             if(rr[ch[k][d]]<rr[k])rotate(k,d^1);
     58         }
     59         bool del(int &k,const int &x)
     60         {
     61             if(!k)return 0;
     62             if(x==w[k])
     63             {
     64                 if(c[k]>1){c[k]--,s[k]--;return 1;}
     65                 if(!ch[k][0]){k=ch[k][1];return 1;}
     66                 if(!ch[k][1]){k=ch[k][0];return 1;}
     67                 if(rr[ch[k][0]]<rr[ch[k][1]])rotate(k,1);
     68                 else rotate(k,0);
     69                 return del(k,x);
     70             }
     71             int d=x>w[k];
     72             if(del(ch[k][d],x))
     73             {
     74                 s[k]--;
     75                 return 1;
     76             }
     77             else return 0;
     78         }
     79         int findrank(int k,const int &x)
     80         {
     81             if(!k)return 0;
     82             int pp=(ch[k][0]?s[ch[k][0]]:0);
     83             if(x==w[k])return pp;
     84             if(x>w[k])return pp+c[k]+findrank(ch[k][1],x);
     85             return findrank(ch[k][0],x);
     86         }
     87         int findwei(int k,const int &x)
     88         {
     89             if(!k)return 0;
     90             int pp=(ch[k][0]?s[ch[k][0]]:0);
     91             if(x<=pp)return findwei(ch[k][0],x);
     92             if(x>pp+c[k])return findwei(ch[k][1],x-pp-c[k]);
     93             return w[k];
     94         
     95         }
     96         void findqian(int k,const int &x,int &ans)
     97         {
     98             if(!k)return ;
     99             if(x>w[k])ans=w[k],findqian(ch[k][1],x,ans);
    100             else findqian(ch[k][0],x,ans);
    101         }
    102         void findhou(int k,const int &x,int &ans)
    103         {
    104             if(!k)return ;
    105             if(x<w[k])ans=w[k],findhou(ch[k][0],x,ans);
    106             else findhou(ch[k][1],x,ans);
    107         }
    108     public:
    109         void add(int x){add(root,x);}
    110         void del(int x){del(root,x);}
    111         int findrank(int x){return findrank(root,x);}
    112         int findwei(int x){return findwei(root,x);}
    113         int findqian(int x)
    114         {
    115             int ans=0;findqian(root,x,ans);
    116             return ans;
    117         }
    118         int findhou(int x)
    119         {
    120             int ans=0;findhou(root,x,ans);
    121             return !ans?inf:ans;
    122         }
    123 }t[200020];
    124 int qi[50050];
    125 void build(int k,int l,int r,int x)
    126 {
    127     t[k].l=l,t[k].r=r,t[k].add(qi[x]);
    128     if(l==r)return ;int mid=(l+r)>>1;
    129     if(x<=mid)build(k<<1,l,mid,x);
    130     else build(k<<1|1,mid+1,r,x);
    131 }
    132 int findrank(int k,int l,int r,int x)
    133 {
    134     if(t[k].l>=l&&t[k].r<=r)return t[k].findrank(x);
    135     int mid=(t[k].l+t[k].r)>>1,p1=k<<1,p2=p1|1;
    136     if(r<=mid)return findrank(p1,l,r,x);
    137     if(l>mid)return findrank(p2,l,r,x);
    138     return findrank(p1,l,r,x)+findrank(p2,l,r,x);
    139 }
    140 int findqian(int k,int l,int r,int x)
    141 {
    142     if(t[k].l>=l&&t[k].r<=r)return t[k].findqian(x);
    143     int mid=(t[k].l+t[k].r)>>1,p1=k<<1,p2=p1|1;
    144     if(r<=mid)return findqian(p1,l,r,x);
    145     if(l>mid)return findqian(p2,l,r,x);
    146     return max(findqian(p1,l,r,x),findqian(p2,l,r,x));
    147 }
    148 int findhou(int k,int l,int r,int x)
    149 {
    150     if(t[k].l>=l&&t[k].r<=r)return t[k].findhou(x);
    151     int mid=(t[k].l+t[k].r)>>1,p1=k<<1,p2=p1|1;
    152     if(r<=mid)return findhou(p1,l,r,x);
    153     if(l>mid)return findhou(p2,l,r,x);
    154     return min(findhou(p1,l,r,x),findhou(p2,l,r,x));
    155 }
    156 int findwei(int l,int r,int x)
    157 {
    158     int ll=0,rr=inf,mid,ans;
    159     while(ll<=rr)
    160     {
    161         mid=(ll+rr)>>1;
    162         int rank=findrank(1,l,r,mid)+1;
    163         if(rank<=x)ans=mid,ll=mid+1;else rr=mid-1;
    164     }
    165     return findqian(1,l,r,ans+1);
    166 }
    167 void change(int k,int x,int w)
    168 {
    169     t[k].del(qi[x]),t[k].add(w);
    170     if(t[k].l==t[k].r)return ;
    171     int mid=(t[k].l+t[k].r)>>1;
    172     if(x<=mid)change(k<<1,x,w);
    173     else change(k<<1|1,x,w);
    174 }
    175 int n,m;
    176 int CSC()
    177 {
    178     freopen("in.in","r",stdin);
    179     freopen("out.out","w",stdout);
    180     inin(n),inin(m);
    181     re(i,1,n)inin(qi[i]);
    182     re(i,1,n)build(1,1,n,i);
    183     re(i,1,m)
    184     {
    185         int opt,q,ww,e;
    186         inin(opt);
    187         if(opt==1)
    188         {
    189             inin(q),inin(ww),inin(e);
    190             printf("%d
    ",findrank(1,q,ww,e)+1);
    191         }
    192         else if(opt==2)
    193         {
    194             inin(q),inin(ww),inin(e);
    195             printf("%d
    ",findwei(q,ww,e));
    196         }
    197         else if(opt==3)
    198         {
    199             inin(q),inin(ww);
    200             change(1,q,ww);qi[q]=ww;
    201         }
    202         else if(opt==4)
    203         {
    204             inin(q),inin(ww),inin(e);
    205             printf("%d
    ",findqian(1,q,ww,e));
    206         }
    207         else 
    208         {
    209             inin(q),inin(ww),inin(e);int ret=findhou(1,q,ww,e);
    210 //            printf("%d
    ",ret==inf?0:ret);
    211             printf("%d
    ",ret);
    212         }
    213     }
    214     return 0;
    215 }
  • 相关阅读:
    view 的继承关系
    dos 下小tip
    Required diagnostic data collection for RMAN backup
    数据库应用设计设计报告
    程序 从存储卡 内存卡 迁移到 SD卡
    c++ 参赛设置
    c++ 用构造函数
    Ip
    error C3872: “0x3000”: 此字符不允许在标识符中使用
    机器字长 32位与64位的区别
  • 原文地址:https://www.cnblogs.com/HugeGun/p/5150875.html
Copyright © 2020-2023  润新知