【题目分析】

听说是树套树。(雾)

怒写树状数组套主席树,然后就Rank1了。23333

单点修改,区间查询+k大数查询=树状数组套主席树。

【代码】

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>

#include <set>
#include <map>
#include <string>
#include <algorithm>
#include <vector>
#include <iostream>
#include <queue>
using namespace std;

#define maxn 50005
#define mlog 20

int read()
{
    int x=0,f=1; char ch=getchar();
    while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();}
    while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
    return x*f;
}

int n,m;
int rt[maxn<<1],a[maxn],b[maxn<<1],cnt=0,tot=0,sum,rnk,TMP;
int ls[maxn<<6],rs[maxn<<6],siz[maxn<<6];
int L[maxn],R[maxn],opt[maxn],x[maxn],y[maxn],z[maxn];

void ins(int o1,int & o2,int l,int r,int x,int f)
{
//    printf("ins %d %d %d %d %d %d\n",o1,o2,l,r,x,f);
    o2=++tot;
    siz[o2]=siz[o1]+f;
    if (l==r) return ;
    int mid=(l+r)/2;
    if (x<=mid) rs[o2]=rs[o1],ins(ls[o1],ls[o2],l,mid,x,f);
    else ls[o2]=ls[o1],ins(rs[o1],rs[o2],mid+1,r,x,f);
    return ;
}

void ready(int l,int r)
{
//  cout<<"ready for "<<l<<" "<<r<<endl;
    l--;
    L[0]=R[0]=0;
    for (int j=l;j;j-=j&(-j)) L[++L[0]]=rt[j];
    for (int j=r;j;j-=j&(-j)) R[++R[0]]=rt[j];
//  cout<<"L "; for (int j=1;j<=L[0];++j) cout<<L[j]<<" "; cout<<endl;
//  cout<<"R "; for (int j=1;j<=R[0];++j) cout<<R[j]<<" "; cout<<endl;
//  cout<<"L "; for (int j=1;j<=L[0];++j) cout<<siz[L[j]]<<" "; cout<<endl;
//  cout<<"R "; for (int j=1;j<=R[0];++j) cout<<siz[R[j]]<<" "; cout<<endl;
}

void cholef()
{
//  cout<<"choose left"<<endl;
    for (int i=1;i<=L[0];++i) L[i]=ls[L[i]];
    for (int i=1;i<=R[0];++i) R[i]=ls[R[i]];
}

void chorig()
{
//  cout<<"choose right"<<endl;
    for (int i=1;i<=L[0];++i) L[i]=rs[L[i]];
    for (int i=1;i<=R[0];++i) R[i]=rs[R[i]];
}

int taksum()
{
    int ret=0;
    for (int i=1;i<=L[0];++i) ret-=siz[ls[L[i]]];
    for (int i=1;i<=R[0];++i) ret+=siz[ls[R[i]]];
    return ret;
}

int qrnk(int l,int r,int x)
{
//  printf("qrnk %d %d %d\n",l,r,x);
    if (l==r) return 1;
    int mid=(l+r)/2,tmp=taksum();
//  cout<<"take sum "<<tmp<<endl;
    if (x<=mid)  return cholef(),qrnk(l,mid,x);
    else return chorig(),tmp+qrnk(mid+1,r,x);
}

int qnum(int l,int r,int x)
{
    if (l==r) return l;
    int mid=(l+r)/2,tmp=taksum();
    if (x<=tmp) return cholef(),qnum(l,mid,x);
    else return chorig(),qnum(mid+1,r,x-tmp);
}

int main()
{
    n=read();m=read();
    for (int i=1;i<=n;++i) scanf("%d",&a[i]),b[++cnt]=a[i];
    for (int i=1;i<=m;++i)
    {
        scanf("%d%d%d",&opt[i],&x[i],&y[i]);
        if (opt[i]!=3) scanf("%d",&z[i]);
        if (opt[i]==3) b[++cnt]=y[i];
        if (opt[i]==4||opt[i]==5) b[++cnt]=z[i];
    }
    sort(b+1,b+cnt+1);
    cnt=unique(b+1,b+cnt+1)-b-1;
    for (int i=1;i<=n;++i) a[i]=lower_bound(b+1,b+cnt+1,a[i])-b;
    for (int i=1;i<=m;++i)
    {
        if (opt[i]==1||opt[i]==4||opt[i]==5)z[i]=lower_bound(b+1,b+cnt+1,z[i])-b;
        if (opt[i]==3) y[i]=lower_bound(b+1,b+cnt+1,y[i])-b;
    }
//  cout<<endl<<endl;
//  for (int i=1;i<=cnt;++i) cout<<i<<" ";cout<<endl;
//  for (int i=1;i<=cnt;++i) cout<<b[i]<<" "; cout<<endl;
//  for (int i=1;i<=m;++i) cout<<opt[i]<<" "<<x[i]<<" "<<y[i]<<" "<<z[i]<<endl;
//  cout<<endl<<endl;
    for (int i=1;i<=n;++i)
        for (int j=i;j<=n;j+=j&(-j))
            ins(rt[j],rt[j],1,cnt,a[i],1);
    for (int i=1;i<=m;++i)
    {
        switch(opt[i])
        {
            case 1:
                ready(x[i],y[i]);
                printf("%d\n",qrnk(1,cnt,z[i]));
            break;
            case 3:
                for (int j=x[i];j<=n;j+=j&(-j))
                {
                    ins(rt[j],rt[j],1,cnt,a[x[i]],-1);
                    ins(rt[j],rt[j],1,cnt,y[i],1);
                }
                a[x[i]]=y[i];
            break;
            case 2:
                ready(x[i],y[i]);
                printf("%d\n",b[qnum(1,cnt,z[i])]);
            break;
            case 4:
                ready(x[i],y[i]);
                rnk=qrnk(1,cnt,z[i]);
//              printf("rnk is %d\n",rnk);
                ready(x[i],y[i]);
                printf("%d\n",b[qnum(1,cnt,rnk-1)]);
            break;
            case 5:
                ready(x[i],y[i]);
                TMP=0;
                TMP-=qrnk(1,cnt,z[i]);
                ready(x[i],y[i]);
                TMP+=qrnk(1,cnt,z[i]+1);
//              printf("it s have %d\n",TMP);
                ready(x[i],y[i]);
                rnk=qrnk(1,cnt,z[i]);
                ready(x[i],y[i]);
                printf("%d\n",b[qnum(1,cnt,rnk+TMP)]);

        }
    }
}

  

BZOJ 3196 Tyvj 1730 二逼平衡树 ——树状数组套主席树的更多相关文章

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

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

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

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

  3. bzoj 3196/ Tyvj 1730 二逼平衡树 (线段树套平衡树)

    3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description ...

  4. BZOJ - 3196 Tyvj 1730 二逼平衡树 (线段树套treap)

    题目链接 区间线段树套treap,空间复杂度$O(nlogn)$,时间复杂度除了查询区间k大是$O(log^3n)$以外都是$O(log^2n)$的. (据说线段树套线段树.树状数组套线段树也能过?) ...

  5. 【BZOJ】3196: Tyvj 1730 二逼平衡树(区间第k小+树套树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3196 Treap+树状数组 1WA1A,好伤心,本来是可以直接1A的,这次开始我并没有看题解,就写出 ...

  6. bzoj 3196: Tyvj 1730 二逼平衡树

    #include<cstdio> #include<ctime> #include<cstdlib> #include<iostream> #defin ...

  7. BZOJ 3196 Tyvj 1730 二逼平衡树 树套树 线段树 treap

    http://www.lydsy.com/JudgeOnline/problem.php?id=3196 http://hzwer.com/2734.html 线段树套treap,似乎splay也可以 ...

  8. BZOJ 3196 Tyvj 1730 二逼平衡树:线段树套splay

    传送门 题意 给你一个长度为 $ n $ 有序数列 $ a $ ,进行 $ m $ 次操作,操作有如下几种: 查询 $ k $ 在区间 $ [l,r] $ 内的排名 查询区间 $ [l,r] $ 内排 ...

  9. bzoj 3196 Tyvj 1730 二逼平衡树【线段树 套 splay】

    四舍五入就是个暴力. 对于线段树的每个区间都开一棵按权值排序的splay 对于第二个操作,二分一下,每次查询mid的排名,复杂度 $ O(nlog(n)^{3}) $ 其余的操作都是$ O(nlog( ...

随机推荐

  1. 数据结构作业——ギリギリ eye(贪心+优先队列/贪心+并查集)

    ギリギリ eye Description A.D.1999,由坠落地球的“谜之战舰”带来的 Over Technology,揭示了人类历史和远古文明之间的丝丝联系, 促使人类终止彼此间的战争,一方面面 ...

  2. python面向对象初级(七)

    概述 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发“更快更好更强...” 面向过程编程最易被初学 ...

  3. Python Day8

    Socket Socket是网络编程的一个抽象概念.通常我们用一个Socket表示"打开了一个网络链接",而打开一个Socket需要知道目标计算机的IP地址和端口号,再指定协议类型 ...

  4. 简单的c# TCP通讯(TcpListener)

      简单的c# TCP通讯(TcpListener) C# 的TCP Socket (同步方式) C# 的TCP Socket (异步方式) C# 的tcp Socket设置自定义超时时间 C# TC ...

  5. Java排序算法——希尔排序

    package sort; //================================================= // File Name : ShellSort //------- ...

  6. 【转】Java enum的用法详解

    用法一:常量 在JDK1.5 之前,我们定义常量都是: public static fianl.... .现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法. p ...

  7. ueditor 百度编辑器,取消或自定义右键菜单

    如图:有2种自定义方法,一种是改源码,一种是初始化 初始化,如下代码: var ue = UE.getEditor('XXXid',{ // contextMenu:[ {label:'', cmdN ...

  8. 基于dom的xss漏洞原理

    原文:http://www.anying.org/thread-36-1-1.html转载必须注明原文地址最近看到网络上很多人都在说XSS我就借着暗影这个平台发表下自己对这一块的一些认识.其实对于XS ...

  9. CSS3按钮效果

    来自codepen,http://codepen.io/PalashSharma20/pen/YWBAgN 知识点:屏幕居中.transform.transition.transition-delay ...

  10. C/C++学习链接

    C/C++堆和栈的区别:http://blog.csdn.net/hairetz/article/details/4141043