hdu 6621 K-th Closest Distance 杭电多校第4场

传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6621

队友一上来分块RE了一发,搞得我也想分块,结果lts一声主席树,然后就发现是主席树板题了。。。

直接权值主席树,下标表示值,记录的sum表示当前值的个数就行了,然后二分答案,得到上下界,用rt[r]-rt[l-1]去找就行了。

#include
#define maxl 100010
using namespace std;

const int nn=1e6;

int n,m,tot,ans;
int rt[maxl],a[maxl];
struct node
{
    int ls,rs,sum;
}tree[maxl*10*35];

inline void insert(int num,int &x,int l,int r)
{
    tree[++tot]=tree[x];x=tot;
    ++tree[x].sum;
    if(l==r) return;
    int mid=(l+r)>>1;
    if(num<=mid)
        insert(num,tree[x].ls,l,mid);
    else
        insert(num,tree[x].rs,mid+1,r);
}

inline void prework()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    tree[0].ls=tree[0].rs=tree[0].sum=0;
    rt[0]=0;
    tot=0;
    for(int i=1;i<=n;i++)
    {
        rt[i]=rt[i-1];
        insert(a[i],rt[i],1,nn);
    }
}

inline int query(int i,int j,int l,int r,int i1,int j1)
{
    if(i1==l && j1==r)
        return tree[j].sum-tree[i].sum;
    int mid=(i1+j1)>>1,ret;
    if(r<=mid)
        ret=query(tree[i].ls,tree[j].ls,l,r,i1,mid);
    else if(l>mid)
        ret=query(tree[i].rs,tree[j].rs,l,r,mid+1,j1);
    else
    {
        ret=query(tree[i].ls,tree[j].ls,l,mid,i1,mid);
        ret+=query(tree[i].rs,tree[j].rs,mid+1,r,mid+1,j1);
    }
    return ret;
}

inline bool jug(int l,int r,int mid,int p,int k)
{
    int up=min(p+mid,nn),lo=max(1,p-mid);
    int sum=query(rt[l-1],rt[r],lo,up,1,nn);
    if(sum>1;
            if(!jug(lo,up,mid,p,k))// 

 

你可能感兴趣的:(主席树)