zoukankan      html  css  js  c++  java
  • bzoj 3196 树套树模板

        然而我还是在继续刷水题。。。

        终于解开了区间第k大的心结。。。

        比较裸的线段树套平衡树,比较不好想的是求区间第k大时需要二分一下答案,然后问题就转化为了第一个操作。复杂度nlog3n。跑的比较慢。。。

        在查前驱后继的时候写错了。。。如果要直接赋值ans的话前驱是k[x]<=z,后继是k[x]<z,如果都写<的话需要取max和min。。。(不是第一次犯这种错了)

       

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #define lc x*2,l,mid
      6 #define rc x*2+1,mid+1,r
      7 #define ls(x) ch[x][0]
      8 #define rs(x) ch[x][1]
      9 #define inf 0x3f3f3f3f
     10 using namespace std;
     11 int n,m;
     12 int root[50005*50];
     13 int size[50005*50],k[50005*50];
     14 int ch[50005*50][2],fa[50005*50];
     15 int a[50005];
     16 int cnt;
     17 inline void push_up(int x)
     18 {
     19     size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
     20     return ;
     21 }
     22 inline void rotate(int p)
     23 {
     24     int q=fa[p],y=fa[q],x=(ch[q][1]==p);
     25     ch[q][x]=ch[p][x^1];fa[ch[q][x]]=q;
     26     ch[p][x^1]=q;fa[q]=p;fa[p]=y;
     27     if(y)
     28     {
     29         if(ls(y)==q)ch[y][0]=p;
     30         else ch[y][1]=p;
     31     }
     32     push_up(q);push_up(p);
     33 }
     34 inline void splay(int now,int x)
     35 {
     36     for(int y;y=fa[x];rotate(x))
     37     {
     38         if(fa[y])
     39         {
     40             if((ls(y)==x&&ls(fa[y])==y)||(rs(y)==x&&rs(fa[y])==y))rotate(y);
     41             else rotate(x);
     42         }
     43     }
     44     root[now]=x;
     45 }
     46 inline void insert(int now,int x,int z)
     47 {
     48     size[x]++;
     49     while(ch[x][k[x]<z])x=ch[x][k[x]<z],size[x]++;
     50     ch[x][k[x]<z]=++cnt;fa[cnt]=x;size[cnt]=1;k[cnt]=z;splay(now,cnt);
     51 }
     52 inline void build(int x,int l,int r)
     53 {
     54     root[x]=++cnt;k[cnt]=a[l];size[cnt]=1;
     55     for(int i=l+1;i<=r;i++)insert(x,root[x],a[i]);
     56     int mid=(l+r)>>1;
     57     if(l<r)build(lc),build(rc);
     58     return ; 
     59 }
     60 inline int fd(int x,int z)
     61 {
     62    int ans=0;
     63    while(x)    
     64    {
     65          if(k[x]>z)
     66          {
     67               x=ch[x][0];
     68       }
     69       else ans+=size[ch[x][0]]+1,x=ch[x][1];
     70    }
     71    return ans;
     72 }
     73 inline int qur(int x,int l,int r,int ll,int rr,int kk)
     74 {
     75     if(ll<=l&&rr>=r)
     76     {
     77         return fd(root[x],kk);
     78     }
     79     int mid=(l+r)>>1;
     80     int ans=0;
     81     if(ll<=mid)ans+=qur(lc,ll,rr,kk);
     82     if(rr>mid)ans+=qur(rc,ll,rr,kk);
     83     return ans;
     84 }
     85 inline int find(int x,int z)
     86 {
     87     if(k[x]==z)return x;
     88     while(ch[x][k[x]<z])
     89     {
     90         x=ch[x][k[x]<z];if(k[x]==z)return x;
     91     }
     92     return 0;
     93 }
     94 inline void del(int now,int x)
     95 {
     96     splay(now,x);
     97     if(!ch[x][0])root[now]=ch[x][1],fa[ch[x][1]]=0;
     98     else if(!ch[x][1])root[now]=ch[x][0],fa[ch[x][0]]=0;
     99     else 
    100     {
    101         fa[ch[x][0]]=0;int tmp=ch[x][0];
    102         while(ch[tmp][1])tmp=ch[tmp][1];
    103         splay(now,tmp);ch[tmp][1]=ch[x][1];fa[ch[x][1]]=tmp;push_up(tmp);
    104     }
    105 }
    106 inline void gai(int x,int l,int r,int pos,int z)
    107 {
    108     insert(x,root[x],z);
    109     int x1=find(root[x],a[pos]);
    110     del(x,x1);
    111     if(l==r)return ;
    112     int mid=(l+r)>>1;
    113     if(pos<=mid)gai(lc,pos,z);
    114     else gai(rc,pos,z);
    115 }
    116 inline int pre(int x,int z)
    117 {
    118     int ans=-inf;
    119     while(ch[x][k[x]<=z])
    120     {
    121         if(k[x]<=z)ans=k[x];
    122         x=ch[x][k[x]<=z];
    123     }if(k[x]<=z)ans=max(ans,k[x]);
    124     return ans;
    125 }
    126 inline int suc(int x,int z)
    127 {
    128     int ans=inf;
    129     while(ch[x][k[x]<z])
    130     {
    131         if(k[x]>=z)ans=k[x];
    132         x=ch[x][k[x]<z];
    133     }if(k[x]>=z)ans=min(ans,k[x]);
    134     return ans;
    135 }
    136 inline int qur_pre(int x,int l,int r,int ll,int rr,int kk)
    137 {
    138     if(l>=ll&&r<=rr)
    139     {
    140         return pre(root[x],kk);
    141     }
    142     int ans=-inf;
    143     int mid=(l+r)>>1;
    144     if(ll<=mid)ans=max(ans,qur_pre(lc,ll,rr,kk));
    145     if(rr>mid)ans=max(ans,qur_pre(rc,ll,rr,kk));
    146     return ans;
    147 }
    148 inline int qur_suc(int x,int l,int r,int ll,int rr,int kk)
    149 {
    150     if(l>=ll&&r<=rr)
    151     {
    152         return suc(root[x],kk);
    153     }
    154     int ans=inf;
    155     int mid=(l+r)>>1;
    156     if(ll<=mid)ans=min(ans,qur_suc(lc,ll,rr,kk));
    157     if(rr>mid)ans=min(ans,qur_suc(rc,ll,rr,kk));
    158     return ans;
    159 }
    160 int mn,mx;
    161 int main()
    162 {
    163     scanf("%d%d",&n,&m);mn=inf;mx=-inf;
    164     for(int i=1;i<=n;i++)
    165     {
    166         scanf("%d",&a[i]);mn=min(mn,a[i]);mx=max(mx,a[i]);
    167     }
    168     build(1,1,n);
    169     for(int i=1;i<=m;i++)
    170     {
    171         int t1;
    172         scanf("%d",&t1);
    173         int l,r,kk;
    174         if(t1==1)
    175         { 
    176            scanf("%d%d%d",&l,&r,&kk);
    177            printf("%d
    ",qur(1,1,n,l,r,kk-1)+1);
    178         }
    179         else if(t1==2)
    180         {
    181             scanf("%d%d%d",&l,&r,&kk);
    182             int ha=mn;int ta=mx;
    183             while(ha<=ta)
    184             {
    185                 int mid=(ha+ta)>>1;
    186                 if(qur(1,1,n,l,r,mid)<kk)ha=mid+1;
    187                 else ta=mid-1;
    188             }
    189             printf("%d
    ",ha);
    190         }
    191         else if(t1==3)
    192         {
    193             scanf("%d%d",&l,&kk);
    194             gai(1,1,n,l,kk);a[l]=kk;
    195         }
    196         else if(t1==4)
    197         {
    198             scanf("%d%d%d",&l,&r,&kk);
    199             printf("%d
    ",qur_pre(1,1,n,l,r,kk-1));
    200         }
    201         else 
    202         {
    203             scanf("%d%d%d",&l,&r,&kk);
    204             printf("%d
    ",qur_suc(1,1,n,l,r,kk+1));
    205         }
    206     }
    207     return 0;
    208 }
  • 相关阅读:
    linux下,webpack热重载无效的解决方法
    前端异步编程之Promise和async的用法
    防呆设计(内容摘录)
    GUI 图形用户界面 [学习笔记]
    15条JavaScript最佳实践【转】
    2013-11-02 【webrebuild广州站】分享会纪要
    关于自控力
    记录一次抖音小程序严重bug(组件样式继承问题)
    微信 头条小程序 记录一次电商项目倒计时活动优化
    微信/头条小程序如何确保异步请求执行完后再执行各页面的onLoad方法
  • 原文地址:https://www.cnblogs.com/ezyzy/p/6146122.html
Copyright © 2011-2022 走看看