BZOJ 1901 Dynamic Rankings 树董事长

标题效果:间隔可以改变k少

我的两个天树牌主席。。。

隔断Count On A Tree 之后我一直认为,随着树的主席的变化是分域林木覆盖率可持久段树。

。。

事实上,我是误导。。。

尼可持久化线段树毛关系都木有啊!!

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


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

1.外层树状数组

2.里层线段树

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

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

5.正常依照普通的树套树往里插即可了。

7.询问时把log个线段树放在一起跑(不要看我的代码,我的代码写的是log^3的)

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
", Bisection(x,y,k) );
        else
            scanf("%d%d",&x,&y),Downdate(x,a[x]),a[x]=y,Update(x,a[x]);
    }
}


版权声明:本文博主原创文章,博客,未经同意不得转载。

原文地址:https://www.cnblogs.com/bhlsheji/p/4914043.html