传送门

主席树的常数蜜汁优越,在BZOJ上跑了rnk1。

做法很简单,主席树套BIT。

1-3做法很简单,第四个和第五个做法转换成前两个就行了。

//BZOJ 3196
//by Cydiater
//2016.12.10
#include <iostream>
#include <queue>
#include <map>
#include <ctime>
#include <cmath>
#include <cstring>
#include <string>
#include <iomanip>
#include <algorithm>
#include <cstdlib>
#include <cstdio>
#include <bitset>
#include <set>
#include <vector>
using namespace std;
#define ll long long
#define up(i,j,n)       for(int i=j;i<=n;i++)
#define down(i,j,n)     for(int i=j;i>=n;i--)
#define cmax(a,b)       a=max(a,b)
#define cmin(a,b)       a=min(a,b)
#define FILE "psh"
const int MAXN=5e4+5;
const int oo=0x3f3f3f3f;
inline int read(){
    char ch=getchar();int x=0,f=1;
    while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int N,M,root[MAXN<<1],arr[MAXN],fsort[MAXN<<1],rnum,cnt=0,top[2],preL[MAXN],preR[MAXN],tmpL[MAXN],tmpR[MAXN],TMP;
struct Chair_man_Tree{
    int son[2],sum;
}t[MAXN<<6];
struct Query{
    int opt,L,R,pos,K;
}query[MAXN];
namespace solution{
    inline int lowbit(int i){return ((i)&(-i));}
    int NewNode(int sum,int son0,int son1){
        t[++cnt].sum=sum;t[cnt].son[0]=son0;t[cnt].son[1]=son1;
        return cnt;
    }
    void insert(int leftt,int rightt,int &Root,int last,int pos){
        Root=NewNode(t[last].sum+1,t[last].son[0],t[last].son[1]);
        int mid=(leftt+rightt)>>1;
        if(leftt==rightt)   return;
        if(pos<=mid)     insert(leftt,mid,t[Root].son[0],t[last].son[0],pos);
        else            insert(mid+1,rightt,t[Root].son[1],t[last].son[1],pos);
    }
    void PushTree(int L,int R){
        top[0]=top[1]=0;
        preL[++top[0]]=root[(L-1==0?0:(N+L-1))];
        preR[++top[1]]=root[R+N];
        for(int j=L-1;j>=1;j-=lowbit(j)) preL[++top[0]]=root[j];
        for(int j=R;j>=1;j-=lowbit(j))       preR[++top[1]]=root[j];
    }
    void ChooseLeft(){
        up(i,1,top[0])preL[i]=t[preL[i]].son[0];
        up(i,1,top[1])preR[i]=t[preR[i]].son[0];
    }
    void ChooseRight(){
        up(i,1,top[0])preL[i]=t[preL[i]].son[1];
        up(i,1,top[1])preR[i]=t[preR[i]].son[1];
    }
    int Col(){
        int sum=0;
        up(i,1,top[0])sum-=t[t[preL[i]].son[0]].sum;
        up(i,1,top[1])sum+=t[t[preR[i]].son[0]].sum;
        return sum;
    }
    void Prepare(){
        rnum=N=read();M=read();
        up(i,1,N)arr[i]=fsort[i]=read();
        up(i,1,M){
            query[i].opt=read();
            if(query[i].opt==3){
                query[i].pos=read();query[i].K=read();
                fsort[++rnum]=query[i].K;continue;
            }
            query[i].L=read();query[i].R=read();query[i].K=read();
            if(query[i].opt==4||query[i].opt==5)
                fsort[++rnum]=query[i].K;
        }
        sort(fsort+1,fsort+rnum+1);
        rnum=unique(fsort+1,fsort+rnum+1)-(fsort+1);
        up(i,1,N){
            arr[i]=lower_bound(fsort+1,fsort+rnum+1,arr[i])-fsort;
            insert(1,rnum,root[i+N],root[i+N-1],arr[i]);
        }
    }
    int Rank(int leftt,int rightt,int pos){
        if(leftt==rightt){
            TMP=0;
            up(i,1,top[0])TMP-=t[preL[i]].sum;
            up(i,1,top[1])TMP+=t[preR[i]].sum;
            return 1;
        }
        int sum=0,mid=(leftt+rightt)>>1;
        sum=Col();
        if(pos<=mid){
            ChooseLeft();
            return Rank(leftt,mid,pos);
        }else{
            ChooseRight();
            return sum+Rank(mid+1,rightt,pos);
        }
    }
    int Get(int leftt,int rightt,int rnk){
        int sum,mid=(leftt+rightt)>>1;
        if(leftt==rightt)   return fsort[leftt];
        sum=Col();
        if(rnk<=sum){
            ChooseLeft();
            return Get(leftt,mid,rnk);
        }else{
            ChooseRight();
            return Get(mid+1,rightt,rnk-sum);
        }
    }
    void Insert(int leftt,int rightt,int &Root,int pos,int tag){
        if(!Root)Root=NewNode(0,0,0);
        t[Root].sum+=tag;
        if(leftt==rightt)   return;
        int mid=(leftt+rightt)>>1;
        if(pos<=mid) Insert(leftt,mid,t[Root].son[0],pos,tag);
        else        Insert(mid+1,rightt,t[Root].son[1],pos,tag);
    }
    void Slove(){
        up(i,1,M){
            int opt=query[i].opt;
            if(opt==1){
                int L=query[i].L,R=query[i].R,K=lower_bound(fsort+1,fsort+rnum+1,query[i].K)-fsort;
                PushTree(L,R);
                printf("%d\n",Rank(1,rnum,K));
            }
            if(opt==2){
                int L=query[i].L,R=query[i].R,K=query[i].K;
                PushTree(L,R);
                printf("%d\n",Get(1,rnum,K));
            }
            if(opt==3){
                int Pos=query[i].pos,K=query[i].K;
                for(int j=Pos;j<=N;j+=lowbit(j))
                    Insert(1,rnum,root[j],arr[Pos],-1);
                arr[Pos]=lower_bound(fsort+1,fsort+rnum+1,K)-fsort;
                for(int j=Pos;j<=N;j+=lowbit(j))
                    Insert(1,rnum,root[j],arr[Pos],1);
            }
            if(opt==4){
                int L=query[i].L,R=query[i].R,K=lower_bound(fsort+1,fsort+rnum+1,query[i].K)-fsort;
                PushTree(L,R);
                int rank=Rank(1,rnum,K);
                PushTree(L,R);
                printf("%d\n",Get(1,rnum,rank-1));
            }
            if(opt==5){
                int L=query[i].L,R=query[i].R,K=lower_bound(fsort+1,fsort+rnum+1,query[i].K)-fsort;
                PushTree(L,R);
                int rank=Rank(1,rnum,K);
                PushTree(L,R);
                printf("%d\n",Get(1,rnum,rank+TMP));
            }
        }
    }
}
int main(){
    using namespace solution;
    Prepare();
    Slove();
    return 0;
}

BZOJ3196: Tyvj 1730 二逼平衡树的更多相关文章

  1. bzoj3196: Tyvj 1730 二逼平衡树 树套树

    地址:http://www.lydsy.com/JudgeOnline/problem.php?id=3196 题目: 3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec ...

  2. 【线段树套平衡树】【pb_ds】bzoj3196 Tyvj 1730 二逼平衡树

    线段树套pb_ds里的平衡树,在洛谷OJ上测试,后三个测试点TLE #include<cstdio> #include<algorithm> #include<ext/p ...

  3. [bzoj3196]Tyvj 1730 二逼平衡树——线段树套平衡树

    题目 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的数值 4.查 ...

  4. [bzoj3196][Tyvj 1730][二逼平衡树] (线段树套treap)

    Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的数值 4.查询k在 ...

  5. 【分块】bzoj3196 Tyvj 1730 二逼平衡树

    分块 或 树套树. 在每个块中维护一个有序表,查询时各种二分,全都是分块的经典操作,就不详细说了. 块的大小定为sqrt(n*log2(n))比较快. #include<cstdio> # ...

  6. 【带修莫队】【权值分块】bzoj3196 Tyvj 1730 二逼平衡树

    这题用了三种算法写: 分块+二分:O(n*sqrt(n*log(n)) 函数式权值分块:O(n*sqrt(n)) 带修莫队+权值分块:O(n5/3) 结果……复杂度越高的实际上跑得越快……最后这个竟然 ...

  7. 【函数式权值分块】【分块】bzoj3196 Tyvj 1730 二逼平衡树

    #include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define ...

  8. bzoj 3196 Tyvj 1730 二逼平衡树(线段树套名次树)

    3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1807  Solved: 772[Submit][Stat ...

  9. BZOJ 3196: Tyvj 1730 二逼平衡树( 树套树 )

    这道题做法应该很多吧.... 我用了线段树套treap.... -------------------------------------------------------------------- ...

随机推荐

  1. 由于目标计算机积极拒绝,无法连接。 192.168.1.106:8078 说明: 执行当前 Web 请求期间,出现未经处理的异常。

    请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息. 异常详细信息: System.Net.Sockets.SocketException: 由于目标计算机积极拒绝,无法连接. 1 ...

  2. JQuery中隐藏/显示事件函数

    1.$("button").click(function(){ $("p").hide(); });2.如果您的网站包含许多页面,并且您希望您的 jQuery ...

  3. 深入理解SQL注入绕过WAF和过滤机制

    知己知彼,百战不殆 --孙子兵法 [目录] 0x0 前言 0x1 WAF的常见特征 0x2 绕过WAF的方法 0x3 SQLi Filter的实现及Evasion 0x4 延伸及测试向量示例 0x5 ...

  4. android JNI 调用NDK方法

    @import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...

  5. 在windows系统下,在终端快速打开某个路径

    进了一个文件夹,要在这个文件夹上直接打开CMD,而不是在系统C盘打开CMD 1) 在此文件夹窗口内空白区域右键单击(需要同时按住Shift),从菜单中选择"在此处打开命令行窗口"的项:2) 快捷键Al ...

  6. Spring bean依赖注入、bean的装配及相关注解

    依赖注入 Spring主要提供以下两种方法用于依赖注入 基于属性Setter方法注入 基于构造方法注入 Setter方法注入 例子: public class Communication { priv ...

  7. 如何打开、关闭IIS服务器

    问题描述:如题. 使用工具:腾讯云Windows Server 2012 R2 数据中心版 64位中文版. 操作步骤: 1.服务器管理器->IIS

  8. vim 在linux下中如何设置显示行数

     在.vimrc(或/etc/vimrc)文件中输入如下文本: set tabstop=4  set softtabstop=4  set shiftwidth=4  set noexpandtab  ...

  9. 《Note --- Unreal 4 --- B project --- Second UV issue》

    Second uv 可以通过editor来生成: 这部分内容都是在staticMeshEditor这个文件夹下面的代码里: 关于UI的相应机制,有个文件UICommandList.cpp例如我点击st ...

  10. 【原】pageResponse - 让H5适配移动设备全家(移动端适配)

    上一篇文章<为什么选择iPhone5的分辨率作为H5视觉稿尺寸>最后留下了问题:是否需要视觉设计师设计多套的视觉稿供给前端工程师做页面适配呢?按照自己以前的方法,通常会要求设计师设计2套的 ...