zoukankan      html  css  js  c++  java
  • [日常摸鱼]关于离散化

    期末考回来写了一道题(大概在这篇博客之后会发出来)…需要离散化然后我写了半天才写出来…
    QAQ已经是个残废选手啦

    开个博客写一些离散化的东西(主要是序列上问题的离散化)

    大概就算是刚学oi的oier也能看得懂了QAQ


    离散化应该算是一种技巧吧…

    1.经典问题:给一个长度为$n$序列,保证两两不同,求逆序对数,值域$leq 10^{18}$,$nleq 5*10^6$.

    归并排序就不说了(我也没写过),一般是用树状数组做这个的吧~

    但是值域这么大开不下呀怎么办呀~当然是选择离散化了

    比如我们可以这样:

    #define rep(i,n) for(register int i=1;i<=n;i++)
    int n,w[N],rak[N];
    inline bool cmp(int a,int b)
    {
        return w[a]<w[b];
    }
    int main()
    {
        scanf("%d",&n);
        rep(i,n)scanf("%d",&w[i]),rak[i]=i;
        sort(rak+1,rak+n+1,cmp);
        rep(i,n)w[i]=rak[i];
        rep(i,n)printf("%d ",w[i]);
        return 0;
    }

    用这样求出的$rak[i]$就表示了第$i$个位置的数的排名,然后直接赋值就可以开得下了.

    不过这种方法如果有一样的数那么一样的数会有不一样的排名.

    2.区间众数:一个长度为$n$的序列,多次查询区间众数,值域$leq 10^9,nleq 4*10^4$.

    嗯这里只说离散化,其实非常简单啦…因为只要众数所以不管大小关系开个map随便乱搞就行了

    rep(i,n)
    {
        scanf("%d",&w[i]);
        if(!mp[w[i]])
        {
            mp[w[i]]=++cnt;
        }
        w[i]=mp[w[i]];
    }
    rep(i,n)printf("%d ",w[i]);

    3.下面我们把上面两种离散化结合起来:有重复的离散化,需要保持原来的大小关系

    要怎么做呢?我们可以手写一个平衡树查询排名!时间复杂度$O(nlogn)$!

    记录一下有哪些数二分一下就行啦

    int n,cnt,w[N],tw[N],v[N];
    int main()
    {
    	freopen("input.in","r",stdin);
    	scanf("%d",&n);
    	rep(i,n)scanf("%d",&w[i]);memcpy(tw,w,sizeof w);
    	sort(tw+1,tw+n+1);
    	rep(i,n)if(i==1||tw[i]!=tw[i]-1)v[++cnt]=tw[i];
    	rep(i,n)w[i]=lower_bound(v+1,v+cnt+1,w[i])-v;
    	rep(i,n)printf("%d ",w[i]);
    	return 0;
    }
    

    (这个插入代码东西不知道为什么好像挂掉了…)

    当然上面的离散化方法也同样可以放在实数什么的~

    以上~

  • 相关阅读:
    响应式设计
    Flex box 弹性盒子布局
    下拉菜单  -
    html使用技巧
    nth-of-type(n)
    Js中 关于top、clientTop、scrollTop、offsetTop
    仿iPhone滑屏操作
    网页超过一页 点击回到顶部
    linux svn使用
    Linux查看CPU和内存使用情况
  • 原文地址:https://www.cnblogs.com/yoshinow2001/p/8410349.html
Copyright © 2011-2022 走看看