zoukankan      html  css  js  c++  java
  • 洛谷P1168 中位数 的各种做法

    洛谷P1168 中位数
    #include <bits/stdc++.h>
    using namespace std;
    int n,t;
    int b[100005],f[100005],w[100005];    //树状数组 
    struct O{
        int x,i;
    }a[100005];
     bool cmp(const O &a,const O &b){
        return a.x<b.x;
    }
    int main(){
        scanf("%d",&n);
        for (int i=1;i<=n;++i) scanf("%d",&a[i].x),a[i].i=i;
        sort(a+1,a+n+1,cmp);
    
        //离散化
        t=0;        //a[i].x : [0,1e9]
        a[0].x=-1;
        for (int i=1;i<=n;++i){
            if (a[i].x!=a[i-1].x) w[++t]=a[i].x;
            b[a[i].i]=t;
        }
    
        //b[i]   now : [1,n]
        for (int i=1;i<=n;++i){
            for (int j=b[i];j<=n;j+=j&-j) f[j]++;
            if (i&1){    // (i%2!=0)
                int l=1,r=n,mid,x;                // [l,r]
                while (l<r){
                    mid=(l+r)/2;
                    x=0;
                    for (int j=mid;j;j-=j&-j) x+=f[j];
                    if (x<=i/2) l=mid+1; else r=mid;
                }
                printf("%d
    ",w[l]);
            }
        }
         return 0;
     }
    树状数组+二分
    #include <bits/stdc++.h>
    using namespace std;
    int n,t;
    int b[100005],f[200005],w[100005];    //树状数组
    struct O{
        int x,i;
    }a[100005];
    bool cmp(const O &a,const O &b){
        return a.x<b.x;
    }
    int main(){
        scanf("%d",&n);
        for (int i=1;i<=n;++i) scanf("%d",&a[i].x),a[i].i=i;
        sort(a+1,a+n+1,cmp);
        
        //离散化
        t=0;        //a[i].x : [0,1e9]
        a[0].x=-1;
        for (int i=1;i<=n;++i){
            if (a[i].x!=a[i-1].x) w[++t]=a[i].x;
            b[a[i].i]=t;
        }
        
        
        //b[i]   now : [1,n]
        
        
        //!!!!注意 树状数组的上限变成 2^17 
        for (int i=1;i<=n;++i){
            for (int j=b[i];j<=1<<17;j+=j&-j) f[j]++;
            if (i&1){    // (i%2!=0)
                int x=i/2+1,k=0;
                for (int j=1<<17;j;j>>=1) 
                if (x>f[k+j]) x-=f[k+j],k+=j;
                printf("%d
    ",w[k+1]);
            }
        }
    
         return 0;
    }
    树状数组直接定位
    #include <bits/stdc++.h>
    using namespace std;
    int n,t;
    int b[100005],w[100005];
    struct O{
        int x,i;
    }a[100005];
    bool cmp(const O &a,const O &b){
        return a.x<b.x;
    }
    
    int cnt,rt;
    struct node{
        int l,r,s;
    }f[200005];
    int build(int l,int r){
        int u=++cnt;
        if (l==r) return u;
        f[u].s=0;
        f[u].l=build(l,(l+r)/2);
        f[u].r=build((l+r)/2+1,r);
        return u;
    }
    void add(int u,int l,int r,int x){
        f[u].s++;
        if (l==r) return;
        if (x<=(l+r)/2) add(f[u].l,l,(l+r)/2,x);
            else add(f[u].r,(l+r)/2+1,r,x);
    }
    int find(int u,int l,int r,int k){
        if (l==r) return l;
        if (k<=f[f[u].l].s) return find(f[u].l,l,(l+r)/2,k);
            else return find(f[u].r,(l+r)/2+1,r,k-f[f[u].l].s);
    }
    int main(){
        scanf("%d",&n);
        for (int i=1;i<=n;++i) scanf("%d",&a[i].x),a[i].i=i;
        sort(a+1,a+n+1,cmp);
        
        //离散化
        t=0;        //a[i].x : [0,1e9]
        a[0].x=-1;
        for (int i=1;i<=n;++i){
            if (a[i].x!=a[i-1].x) w[++t]=a[i].x;
            b[a[i].i]=t;
        }
        
        //b[i]   now : [1,n]
        rt=build(1,t);
        for (int i=1;i<=n;++i){
            add(rt,1,t,b[i]);
            if (i&1){
                printf("%d
    ",w[find(rt,1,t,i/2+1)]);
            }
        }
         return 0;
    }
    普通线段树
    #include <bits/stdc++.h>
    using namespace std;
    int n,x,rt,t;
    struct node{
        int l,r,s;
    }a[100005*20];
    void add(int &u,int p,int q,int x){
        if (!u) u=++t;
        a[u].s++;
        if (p==q) return;
        if (x<=(p+q)/2) add(a[u].l,p,(p+q)/2,x);
            else add(a[u].r,(p+q)/2+1,q,x);
    }
    int find(int u,int p,int q,int k){
        if (p==q) return p;
        if (k<=a[a[u].l].s) return find(a[u].l,p,(p+q)/2,k);
            else return find(a[u].r,(p+q)/2+1,q,k-a[a[u].l].s);
    }
    int main(){
        scanf("%d",&n);
        for (int i=1;i<=n;++i){
            scanf("%d",&x);
            add(rt,0,1e9,x);
            if (i&1){
                printf("%d
    ",find(rt,0,1e9,i/2+1));
            }
        }
        return 0;
    }
    动态开点线段树(不用离散化)
    #include <bits/stdc++.h>
    using namespace std;
    int n,x,rt,t;
    struct O{
        int l,r,v,s;
    }a[3000005];
    void up(int u){
        a[u].s=a[a[u].l].s+a[a[u].r].s+1;
    }
    void splitS(int u,int k,int &l,int &r){    //前k个位l
        if (!k) {l=0; r=u; return;}
        if (k==a[u].s) {l=u; r=0; return;}
        if (k<=a[a[u].l].s) r=u,splitS(a[u].l,k,l,a[u].l);
        else l=u,splitS(a[u].r,k-a[a[u].l].s-1,a[u].r,r);
        up(u);
    }
    void splitV(int u,int k,int &l,int &r){    //.v<=k的为l 
        if (u==0) {l=r=0; return;}
        if (k<a[u].v) r=u,splitV(a[u].l,k,l,a[u].l);
        else l=u,splitV(a[u].r,k,a[u].r,r);
        up(u);
    }
    int merge(int l,int r){
        if (!l||!r) return l+r;
        if (1ll*rand()*(a[l].s+a[r].s)<1ll*RAND_MAX*a[l].s){
            a[l].r=merge(a[l].r,r); up(l); return l;
        }else{
            a[r].l=merge(l,a[r].l); up(r); return r;
        }
    }
    void Add(int x){
        int A,B;
        a[++t].v=x; a[t].s=1;
        splitV(rt,x,A,B);
        rt=merge(merge(A,t),B);
    }
    int Find(int u,int k){
        if (a[a[u].l].s+1==k) return a[u].v;
        if (k<=a[a[u].l].s) return Find(a[u].l,k);
            else return Find(a[u].r,k-a[a[u].l].s-1);
    }
    int main(){
        scanf("%d",&n);
        for (int i=1;i<=n;++i){
            scanf("%d",&x);
            Add(x);
            if (i&1){
                printf("%d
    ",Find(rt,i/2+1));
            }
        }
        return 0;
    }
    非旋treap
    #include <bits/stdc++.h>
    using namespace std;
    int n,x,rt,t;
    int fa[100005],w[100005],ch[100005][2],s[100005];
    void up(int x){
        s[x]=s[ch[x][0]]+s[ch[x][1]]+1;
    }
    void Rotate(int x){        //一次旋转 
        int y=fa[x],i=ch[y][1]==x;
        ch[fa[y]][ch[fa[y]][1]==y]=x;    
        ch[y][i]=ch[x][i^1];
        ch[x][i^1]=y;
        fa[ch[y][i]]=y;
        fa[x]=fa[y];
        fa[y]=x;
        up(y); up(x);
    }
    void splay(int x){        //把x转到根 
        int y,z;
        while (fa[x]){
            y=fa[x],z=fa[y];
            if (z) (ch[z][0]==y)^(ch[y][0]==x)?Rotate(x):Rotate(y);
            Rotate(x);
        }
    }
    void ADD(int x){
        if (!rt){
            rt=++t;
            w[t]=x;
            s[t]=1;
            return;
        }
        int u=rt;
        while (ch[u][w[u]<x]) u=ch[u][w[u]<x];
        ch[u][w[u]<x]=++t;
        w[t]=x; fa[t]=u;
        splay(t); rt=t;
    }
    void Find(int k){        //找到第k个 
        int u=rt;
        while (1){
            if (k==s[ch[u][0]]+1){
                splay(u); rt=u; return;
            }
            if (k<=s[ch[u][0]]) u=ch[u][0];
                else k=k-s[ch[u][0]]-1,u=ch[u][1];
        }
    }
    int main(){
    //    freopen("data4.in","r",stdin);
    //    freopen("splay.out","w",stdout);
        scanf("%d",&n);
        for (int i=1;i<=n;++i){
            scanf("%d",&x);
            ADD(x);
            if (i&1){
                Find(i/2+1);
                printf("%d
    ",w[rt]);
            }
        }
        return 0;
    }
    普通splay
    #include <bits/stdc++.h>
    using namespace std;
    priority_queue <int,vector<int>,less<int> > a;    //大根 
    priority_queue <int,vector<int>,greater<int> > b;    //小根 
    int n,x;
    int main(){
        scanf("%d",&n);
        for (int i=1;i<=n;++i){
            scanf("%d",&x);
            if (a.empty()||x<=a.top()) a.push(x); else b.push(x);
            while (a.size()>b.size()+1)    b.push(a.top()),a.pop();
            while (a.size()<b.size())    a.push(b.top()),b.pop();
            if (i&1) printf("%d
    ",a.top());
        }
        return 0;
    }
    堆(最优)

    转载请标明出处 http://www.cnblogs.com/cyz666/
  • 相关阅读:
    学习笔记—查找
    水晶报表图表制作问题
    Chrome对最小字体的限制
    Devexpress的ASPxDateEdit控件设置其‘today’ 为客户端当前日期
    水晶报表多表数据源
    System.Web.HttpValueCollection.ThrowIfMaxHttpCollectionKeysExceeded
    利用水晶报表制作甘特图
    水晶报表打印时最后多打印一空白页
    day3学习
    Python高级自动化培训day1
  • 原文地址:https://www.cnblogs.com/cyz666/p/15083794.html
Copyright © 2011-2022 走看看