zoukankan      html  css  js  c++  java
  • [BZOJ4923]K小值查询

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4923

    好题啊!直接做肯定是不行的,我们需要发现一些性质。考虑减去k后对各个数的影响,对于(k,2k](即大于k小于等于2k)的数,它们被减后会小于等于k,但对于>2k的数,减去k后还是大于k的,且那些数的相对大小不变,因为要动态维护第k大,我们可以想到用平衡树,一般用splay,然后对于(k,2k]的数,直接暴力提取,一个个减去k,再暴力插入回去,大于2k的数直接打个标记就好了。我们分析下复杂度,(k,2k]的数至少会减少一半,那么对于每个数,减的次数,也就是插入的次数,最多是logn,总复杂度为nlognlogn

    贴代码:

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    //-----------------------------------------------head-------------------------------------------//
    const int N=100010;
    typedef long long LL;
    const LL inf=1e18;
    int n,q,fa[N],c[N][2],siz[N],lazy[N],rt,s[N],top;
    LL a[N];
    int Write[20];
    inline int read() {int d=0,f=1; char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();} while (c>='0'&&c<='9') d=(d<<3)+(d<<1)+c-48,c=getchar(); return d*f;}
    inline void write(int x){int t=0; if (x<0) putchar('-'),x=-x; for (;x;x/=10) Write[++t]=x%10; if (!t) putchar('0'); for (int i=t;i>=1;i--) putchar((char)(Write[i]+48));}
    inline void pushup(int x){siz[x]=siz[c[x][0]]+siz[c[x][1]]+1;}
    inline void mark(int x,int v){if (!x) return;lazy[x]+=v;a[x]+=v;}
    inline void pushdown(int x){if (!lazy[x]) return; mark(c[x][0],lazy[x]);mark(c[x][1],lazy[x]);lazy[x]=0;}
    inline void build(int &k,int l,int r,int last)
    {
        if (l>r) return; k=(l+r)>>1; fa[k]=last;
        build(c[k][0],l,k-1,k); build(c[k][1],k+1,r,k);
        pushup(k);
    }
    inline void rotate(int x,int &k)
    {
        int y=fa[x],z=fa[y],l=c[y][1]==x,r=l^1;
        if (y==k) k=x; else c[z][c[z][1]==y]=x;
        fa[c[x][r]]=y; fa[y]=x; fa[x]=z;
        c[y][l]=c[x][r]; c[x][r]=y;
        pushup(y); pushup(x);
    }
    inline void splay(int x,int &k)
    {
        while (x!=k)
        {
            int y=fa[x],z=fa[y];
            if (y!=k) if (c[y][0]==x^c[z][0]==y) rotate(x,k); else rotate(y,k);
            rotate(x,k);
        }
    }
    inline int find(int x,int k)
    {
        while (x)
        {
            pushdown(x);
            if (siz[c[x][0]]+1==k) return x;
            if (siz[c[x][0]]+1>k) x=c[x][0]; else k-=siz[c[x][0]]+1,x=c[x][1];
        }
    }
    inline int getpre(int x,int k)
    {
        int res;
        while (x)
        {
            pushdown(x);
            if (a[x]<=k) res=x,x=c[x][1]; else x=c[x][0];
        }
        return res;
    }
    inline int getnxt(int x,int k)
    {
        int res;
        while (x)
        {
            pushdown(x);
            if (a[x]>k) res=x,x=c[x][0]; else x=c[x][1];
        }
        return res;
    }
    inline void dfs(int x)
    {
        if (!x) return;
        pushdown(x);
        dfs(c[x][0]);
        s[++top]=x;
        dfs(c[x][1]);
    }
    inline void insert(int &x,int k,int last)
    {
        if (!x) {x=k;c[x][0]=c[x][1]=0;fa[x]=last;siz[x]=1;return;}
        pushdown(x);
        insert((a[x]>=a[k])?c[x][0]:c[x][1],k,x);
        pushup(x);
    }
    int main()
    {
        n=read(); q=read();
        for (int i=2;i<=n+1;i++) a[i]=read();
        sort(a+2,a+2+n); a[1]=-inf; a[n+2]=inf;
        build(rt,1,n+2,0);
        while (q--)
        {
            int op=read(),k=read();
            if (op==1)
            {
                k=find(rt,k+1);
                splay(k,rt);
                write(a[k]); puts("");
            }
            else
            {
                int x=getpre(rt,k),y=getnxt(rt,k<<1);
                splay(x,rt); splay(y,c[x][1]);
                int z=c[y][0];
                if (z) top=0,dfs(z),fa[z]=c[y][0]=0;
                pushup(y); pushup(x); mark(y,-k);
                if (z) for (int i=1;i<=top;i++) a[s[i]]-=k,insert(rt,s[i],0),splay(s[i],rt);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    ORA-01733: virtual column not allowed here
    五年磨一剑:Java 开源博客 Solo 1.0.0 发布了!
    五年磨一剑:Java 开源博客 Solo 1.0.0 发布了!
    关于Java中equal函数和==的一些区别
    <Android Framework 之路>Android5.1 Camera Framework(四)——框架总结
    Sqlite基本命令集合(linux/fedora/ubuntu)
    简介分布式计算系统的硬件架构
    <Android Framework 之路>Android5.1 Camera Framework(三)
    “调试器的协议与调试对象不兼容”错误的解决
    log4j:WARN Please initialize the log4j system properly.解决方案
  • 原文地址:https://www.cnblogs.com/lujiaju6555/p/7296016.html
Copyright © 2011-2022 走看看