zoukankan      html  css  js  c++  java
  • 主席树总结

    主席树总结

    Wc的主席树
    Xzy的主席树(建议自己多看!!!)

    自己的板子。。。

    洛谷题目

    随便糊一下

    想一想,求i到j中的第k大,是不是就是前j个数把前i个数的影响去掉之后的第k大值(排序实现,但不是暴力...)
    ……(这不是废话?但这道题时刻记住这一种理解方式有利于理解可持久化线段树的实现)
    那么先建一棵主席树,然后只要查询两个时期的线段树,然后找到正好加入的时间点就ojbk了
    说的很简单,至于实现,那就自己模拟研究......

    code

    #include<iostream>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<iomanip>
    #include<algorithm>
    #include<ctime>
    #include<queue>
    #include<stack>
    #define rg register
    #define il inline
    #define lst long long
    #define N 200050
    using namespace std;
    
    int n,Q,cnt;
    int rank[N],root[N];
    struct NUMS{
        int v,num;
    }jlr[N];
    struct TREE{
        int v,ls,rs;
    }ljl[N*20];
    
    il int read()
    {
        rg int s=0,m=1;rg char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')m=-1,ch=getchar();
        while(ch>='0'&&ch<='9')s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
        return s*m;
    }
    
    il int cmp(rg const NUMS &a,rg const NUMS &b){return a.v<b.v;}
    
    void Update(rg int &now,rg int ll,rg int rr,rg int xx)
    //              当前节点,   左边界,   右边界  ,加入的值
    //其实这个函数都是板子
    {
        ljl[++cnt]=ljl[now];
        now=cnt;
        ljl[now].v++;
        if(ll==rr)return;
        rg int mid=(ll+rr)>>1;
        if(xx<=mid)Update(ljl[now].ls,ll,mid,xx);
        else Update(ljl[now].rs,mid+1,rr,xx);
    }
    
    int Query(rg int u,rg int v,rg int ll,rg int rr,rg int kk)
    //在ll-1版本上的u点,在rr版本上的v点,左边界,右边界,要找的标号
    {
        if(ll==rr)return ll;
        rg int num=ljl[ljl[v].ls].v-ljl[ljl[u].ls].v;//(以左孩子为例)
        //Rank指的是v时间的线段树和u时期的线段树之间加了几个点(我们要找中间第k个加入的点)
        rg int mid=(ll+rr)>>1;//递归中"二分"地找
        if(kk<=num)return Query(ljl[u].ls,ljl[v].ls,ll,mid,kk);
        //如果左孩子里面加了比 要找的序号 数量更多的数,去左孩子上find啊(右孩子的类推)
        else return Query(ljl[u].rs,ljl[v].rs,mid+1,rr,kk-num);//算上左孩子上加入的数量造成的贡献
    }
    
    int main()
    {
        n=read(),Q=read();
        for(rg int i=1;i<=n;++i)jlr[i].v=read(),jlr[i].num=i;
        sort(jlr+1,jlr+n+1,cmp);
        for(rg int i=1;i<=n;++i)rank[jlr[i].num]=i;//离散化一波
    
        for(rg int i=1;i<=n;++i)
        {
            root[i]=root[i-1];//按时间顺序建一棵主席树
            Update(root[i],1,n,rank[i]);//把节点都加进去,模拟一下"更新"函数的过程
        }
        for(rg int i=1;i<=n;++i)
        {
            rg int ll=read(),rr=read(),k=read();
            printf("%d
    ",jlr[Query(root[ll-1],root[rr],1,n,k)].v);
        }
        return 0;
    }
    

    题单(来自XZY)

    • [ ] [COGS2316]可持久化线段树
    • [X] [Luogu3834]可持久化线段树
    • [X] [Luogu3919]可持久化数组
    • [ ] [SPOJ10628]Count On a Tree
    • [ ] [BZOJ3514]Codechef MARCH14 GERALD07加强版
    • [ ] [BZOJ3123]森林
    • [ ] [BZOJ4571][SCOI2016]美味
    • [ ] [BZOJ4012][HNOI2015]开店
    • [ ] [BZOJ2006][NOI2010]超级钢琴
    • [ ] [BZOJ1926][SDOI2010]粟粟的书架
    • [ ] [BZOJ3932][CQOI2015]任务查询系统
    • [ ] [BZOJ1146]网络管理
    • [ ] 国家集训队middle
    • [ ] [CF757G] Can Bash Save the Day?
    • [ ] SPOJ/Vjudge To the moon(复习模板)
    • [ ] HDU P4251 The Famous ICPC Team Again
    • [ ] SPOJ P3267 D-query
    • [ ] HDU 5919 Sequence II
    • [ ] 洛谷 P3567 [POI2014]KUR-Couriers
    • [ ] CF813E Army Creation
    • [ ] CF484E Sign on Fence
    • [ ] [BZOJ3551][ONTAK2010]Peaks加强版
    • [ ] [BZOJ4556]字符串
    • [ ] [Luogu2617]Dynamic Ranking
    • [ ] [SYZOJ279]滑稽♂树
  • 相关阅读:
    Android开发工程师文集-1 小时学会SQLite
    Android开发工程师文集-1 小时学会各种Drawable
    Android开发工程师文集-1 小时学会各种Drawable
    Android精通教程-Android入门简介
    Android精通教程-Android入门简介
    AndroidStudio制作登录和注册功能的实现,界面的布局介绍
    AndroidStudio制作登录和注册功能的实现,界面的布局介绍
    Android开发的插件Code Generator与LayoutCreator的安装与使用,提升你的开发效率
    Android开发的插件Code Generator与LayoutCreator的安装与使用,提升你的开发效率
    AndroidStudio项目制作倒计时模块
  • 原文地址:https://www.cnblogs.com/cjoierljl/p/9502412.html
Copyright © 2011-2022 走看看