BZOJ 1901 Dynamic Rankings 主席树

题目大意:可修改的区间第k小

这个主席树卡了我两天。。。切掉Count On A Tree 之后我就一直认为带修改的主席树是树状数组套可持久化线段树。。。其实我被误导了。。。

尼玛带修改的主席树和可持久化线段树毛关系都木有啊!!!

那就是动态的权值线段树啊啊啊啊啊啊啊!!!

好吧这里给不明白主席树的孩纸一些简介:

1.外层树状数组

2.里层线段树

3.线段树动态开节点。仅此而已。和可持久化完全没关系。

4.一个点上的线段树和其他版本毛关系都没有。

5.正常按照普通的树套树往里插就行了。

7.询问时二分答案

8.节点数是nlog^2n

9.看题解要专心。没有第六点你看到了么。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define M 10100
using namespace std;
struct Tree{
    Tree *ls,*rs;
    int num;
}*tree[M],mempool[2002002],*C=mempool;
int n,m,a[M];
void Insert(Tree*&p,int x,int y,int val)
{
    int mid=x+y>>1;
    if(!p) p=C++;
    p->num++;
    if(x==y)
        return ;
    if(val<=mid)
        Insert(p->ls,x,mid,val);
    else
        Insert(p->rs,mid+1,y,val);
}
void Delete(Tree*&p,int x,int y,int val)
{
    int mid=x+y>>1;
    p->num--;
    if(x==y)
        return ;
    if(val<=mid)
        Delete(p->ls,x,mid,val);
    else
        Delete(p->rs,mid+1,y,val);
}
int Get_Ans(Tree*p,int x,int y,int val)
{
    int mid=x+y>>1;
    if(!p)
        return 0;
    if(!p->num)
        return 0;
    if(x==y)
        return p->num;
    if(val<=mid)
        return Get_Ans(p->ls,x,mid,val);
    else
        return (p->ls?p->ls->num:0) + Get_Ans(p->rs,mid+1,y,val);
}
void Update(int x,int y)
{
    for(;x<=n;x+=x&-x)
        Insert(tree[x],0,1000000000,y);
}
void Downdate(int x,int y)
{
    for(;x<=n;x+=x&-x)
        Delete(tree[x],0,1000000000,y);
}
int Get_Ans(int x,int y)
{
    int re=0;
    for(;x;x-=x&-x)
        re+=Get_Ans(tree[x],0,1000000000,y);
    return re;
}
int Bisection(int x,int y,int k)
{
    int l=0,r=1000000000;
    while(l+1<r)
    {
        int mid=l+r>>1;
        if( Get_Ans(y,mid) - Get_Ans(x-1,mid) >= k )
            r=mid;
        else
            l=mid;
    }
    if( Get_Ans(y,l) - Get_Ans(x-1,l) >= k )
        return l;
    return r;
}
int main()
{
    int i,x,y,k;
    char p[10];
    cin>>n>>m;
    for(i=1;i<=n;i++)
        scanf("%d",&a[i]),Update(i,a[i]);
    for(i=1;i<=m;i++)
    {
        scanf("%s",p);
        if(p[0]=='Q')
            scanf("%d%d%d",&x,&y,&k),printf("%d\n", Bisection(x,y,k) );
        else
            scanf("%d%d",&x,&y),Downdate(x,a[x]),a[x]=y,Update(x,a[x]);
    }
}
时间: 2024-10-13 12:19:42

BZOJ 1901 Dynamic Rankings 主席树的相关文章

[BZOJ 1901] Dynamic Rankings 【树状数组套线段树 || 线段树套线段树】

题目链接:BZOJ - 1901 题目分析 树状数组套线段树或线段树套线段树都可以解决这道题. 第一层是区间,第二层是权值. 空间复杂度和时间复杂度均为 O(n log n). 代码 树状数组套线段树 #include <iostream> #include <cstdlib> #include <cstdio> #include <cmath> #include <algorithm> #include <cstring> usin

zoj 2112 Dynamic Rankings(主席树&amp;动态第k大)

Dynamic Rankings Time Limit: 10 Seconds      Memory Limit: 32768 KB The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with the query like to simply find the k-th smallest number of the given N numbers. They

bzoj 1901: Zju2112 Dynamic Rankings -- 主席树,树状数组,哈希

1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MB Description 给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1 ],a[i+2]……a[j]中第k小的数是多少(1≤k≤j-i+1),并且,你可以改变一些a[i]的值,改变后,程序还能针对改 变后的a继续回答上面的问题. Input 第一行有两个正整数n(1≤

BZOJ 1901 Dynamic Rankings 树董事长

标题效果:间隔可以改变k少 我的两个天树牌主席... 隔断Count On A Tree 之后我一直认为,随着树的主席的变化是分域林木覆盖率可持久段树. .. 事实上,我是误导... 尼可持久化线段树毛关系都木有啊!! ! 那就是动态的权值线段树啊啊啊啊啊啊啊!!! 好吧这里给不明确主席树的孩纸一些简单介绍: 1.外层树状数组 2.里层线段树 3.线段树动态开节点.仅此而已.和可持久化全然没关系. 4.一个点上的线段树和其它版本号毛关系都没有. 5.正常依照普通的树套树往里插即可了. 7.询问时

BZOJ 1901 Dynamic Rankings

题面: 1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 8088  Solved: 3364[Submit][Status][Discuss] Description 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1 ],a[i+2]--a[j]中第k小的数是多少(1≤k≤j-i+1),并且,你可以改变

ZOJ -2112 Dynamic Rankings 主席树 待修改的区间第K大

Dynamic Rankings 带修改的区间第K大其实就是先和静态区间第K大的操作一样.先建立一颗主席树, 然后再在树状数组的每一个节点开线段树(其实也是主席树,共用节点), 每次修改的时候都按照树状数组的方式去修改,并且修改那些地方.查询的时候就是查询原主席树+树状数组的值. 代码: 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define Fopen freopen("_in.txt","r&quo

HYSBZ 1901 Dynamic Rankings 树状数组套主席树

ZOJ上面这题内存限制太严格,裸的树套树主席树搞法过不去,BZOJ上面这个放的比较松,可以过. 其实就是利用树状数组维护n颗主席树,然后利用前缀和性质求解第k大. #include <cstdio> #include <cstring> #include <iostream> #include <map> #include <set> #include <vector> #include <string> #include

【BZOJ1901】Dynamic Rankings,树状数组套主席树

Time:2016.05.09 Author:xiaoyimi 转载注明出处谢谢 传送门(权限) 题面 1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec Memory Limit: 128 MB Submit: 6678 Solved: 2777 [Submit][Status][Discuss] Description 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a

BZOJ1901 Zju2112 Dynamic Rankings 【树状数组套主席树】

题目 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]--a[j]中第k小的数是多少(1≤k≤j-i+1),并且,你可以改变一些a[i]的值,改变后,程序还能针对改 变后的a继续回答上面的问题. 输入格式 第一行有两个正整数n(1≤n≤10000),m(1≤m≤10000). 分别表示序列的长度和指令的个数. 第二行有n个数,表示a[1],a[2]--a[n],这些数都小于10^9. 接下来的m