题意:给定一棵树,有点权,不带修改,询问路径点权第K大,强制在线。

这道题建主席树的方法好机智。按照BFS/DFS序建树,对于每个点,建出“这个点到根节点的路径上的点”组成的权值线段树,某个节点的树由父节点的树更改一条链得来。查询时用路径两个端点到根的线段树减去lca到根节点的线段树的2倍就得到了这条路径。注意lca的点权要特殊处理一下,不要把lca多减一次。据说只要分别减去lca和lca的父亲即可,查询的时候传4棵线段树的节点。

于是抖机灵强行传3个节点,单独处理lca,结果RE了一坨…..因为lca的权值小于区间中点的权值并不一定是lca处在[l,r]区间的左半部分,还有可能是lca在[l,r]区间的左边,加句rk[lca]>=l就过了.调了一小时,虚死….

#include<cstdio>

#include<algorithm>

using namespace std;

const int maxn=;

int n,m;

struct edge{

    int to,next;

}lst[maxn<<];int len=;

int first[maxn];

void addedge(int a,int b){

    lst[len].to=b;

    lst[len].next=first[a];

    first[a]=len++;

}

int c[maxn];

int q[maxn];

int depth[maxn],p[maxn][];

void bfs(){

    int head=,tail=;

    depth[]=;

    q[tail++]=;

    int x;

    while(head!=tail){

        x=q[head++];

        for(int pt=first[x];pt;pt=lst[pt].next){

            if(lst[pt].to==p[x][])continue;

            p[lst[pt].to][]=x;

            depth[lst[pt].to]=depth[x]+;

            q[tail++]=lst[pt].to;

        }

        for(int j=;p[x][j];++j)p[x][j+]=p[p[x][j]][j];

    }

}

int LCA(int u,int v){

    if(depth[u]<depth[v])swap(u,v);

    for(int j=;j>=;--j){

        if(depth[p[u][j]]>=depth[v])u=p[u][j];

    }

    if(u==v)return u;

    for(int j=;j>=;--j){

        if(p[u][j]!=p[v][j]){

            u=p[u][j];v=p[v][j];

        }

    }

    return p[u][];

}

struct node{

    int sum;

    node *lch,*rch;

    node(){

        lch=rch=;

        sum=;

    }

}t[maxn*];int cnt=;

int tot=;

node *root[maxn];

int qx;

int seq[maxn],dict[maxn],rk[maxn];

void Insert(node *rt1,node* &rt2,int l,int r){

    ++cnt;rt2=t+cnt;

    if(l==r){

        rt2->sum=rt1->sum+;

        rt2->lch=rt2->rch=t+;

        return;

    }

    int mid=(l+r)>>;

    if(qx<=mid){

        rt2->rch=rt1->rch;

        Insert(rt1->lch,rt2->lch,l,mid);

    }else{

        rt2->lch=rt1->lch;

        Insert(rt1->rch,rt2->rch,mid+,r);

    }

    rt2->sum=rt2->lch->sum+rt2->rch->sum;

}

void build_all(){

    root[]=t+;

    root[]->rch=root[]->lch=t+;

    root[]->sum=;

    for(int i=;i<n;++i){

        qx=rk[q[i]];

        Insert(root[p[q[i]][]],root[q[i]],,tot);

    }

}

bool cmp(const int &x,const int &y){

    return c[x]<c[y];

}

int lca;

int query(node *rt1,node *rt2,node *rt3,int l,int r){

    if(l==r)return l;

    int mid=(l+r)>>;

    int lsum=rt1->lch->sum+rt2->lch->sum-*(rt3->lch->sum);

    if(l<=rk[lca]&&rk[lca]<=mid)lsum++;

    //if(rk[lca]<=mid) 错误的写法.这时rk[lca]可以小于l

    if(qx<=lsum)return query(rt1->lch,rt2->lch,rt3->lch,l,mid);

    else{

        qx-=lsum;

        return query(rt1->rch,rt2->rch,rt3->rch,mid+,r);

    }

}

int main(){

    scanf("%d%d",&n,&m);

    for(int i=;i<=n;++i){

        scanf("%d",c+i);

        seq[i]=i;

    }

    sort(seq+,seq+n+,cmp);

    int old=c[seq[]]-;

    for(int i=;i<=n;++i){

        if(old!=c[seq[i]]){

            old=c[seq[i]];++tot;

            dict[tot]=c[seq[i]];

        }

        rk[seq[i]]=tot;

    }

    int a,b,k;

    for(int i=;i<n;++i){

        scanf("%d%d",&a,&b);

        addedge(a,b);addedge(b,a);

    }

    bfs();

    build_all();

    int lastans=;

    while(m--){

        scanf("%d%d%d",&a,&b,&k);

        a^=lastans;

        qx=k;lca=LCA(a,b);

        lastans=dict[query(root[a],root[b],root[lca],,tot)];

        if(m)printf("%d\n",lastans);

        else printf("%d",lastans);

    }

    return ;

}

bzoj2588 Count on a tree的更多相关文章

  1. 洛谷P2633/bzoj2588 Count on a tree (主席树)

    洛谷P2633/bzoj2588 Count on a tree 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K ...

  2. BZOJ2588 Count on a tree 【树上主席树】

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MB Submit: 7577  Solved: 185 ...

  3. 主席树+dfs SPOJ BZOJ2588 Count on a tree

    这道题我由于智障错误导致一直错. 在树上建主席树,加上lca思想,很简单. #include<bits/stdc++.h> using namespace std; ; struct no ...

  4. [BZOJ2588]Count on a tree(LCA+主席树)

    题面 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个询问 ...

  5. [bzoj2588][count on a tree] (主席树+lca)

    Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始 ...

  6. 【填坑向】spoj COT/bzoj2588 Count on a tree

    这题是学主席树的时候就想写的,,, 但是当时没写(懒) 现在来填坑 = =日常调半天lca(考虑以后背板) 主席树还是蛮好写的,但是代码出现重复,不太好,导致调试的时候心里没底(虽然事实证明主席树部分 ...

  7. BZOJ2588:Count on a tree(主席树)

    Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始 ...

  8. [Bzoj2588]Count on a tree(主席树+LCA)

    Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始 ...

  9. BZOJ2588 SPOJ10628 Count on a tree 【主席树】

    BZOJ2588 Count on a tree 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中l ...

随机推荐

  1. Castle ActiveRecord 二级缓存使用 异常记录

    在 本公司的 IBeamMDAA 框架下,如果是配置为本机调试时,AR的查询缓存工作正常,但如果部署到服务器上,工作不正常,二级缓存配置为使用 MemoryCahcheD 服务器,二级缓存没有能够根据 ...

  2. 多线程下HashMap的死循环问题

    多线程下[HashMap]的问题: 1.多线程put操作后,get操作导致死循环.2.多线程put非NULL元素后,get操作得到NULL值.3.多线程put操作,导致元素丢失. 本次主要关注[Has ...

  3. DTCMS插件的制作实例电子资源管理(一)插件目录结构

    总目录 插件目录结构(一) Admin后台页面编写(二) 前台模板页编写(三) URL重写(四)     本实例旨在以一个实际的项目中的例子来介绍如何在dtcms中制作插件,本系列文章非入门教程,部分 ...

  4. Windows 部署 Redis 群集

    1,下载Redis for windows 的最新版本,解压到 c:\Redis 目录下备用https://github.com/MSOpenTech/redis/releases当前我使用的是 3. ...

  5. ModernUI教程:目录 (完结)

    入门 My first Modern UI app (manually)                         第一个ModernUI应用(手动编写)(已完成) My first Moder ...

  6. 开发WP版本的大菠萝英雄榜

    前言 想当年Team有无数人在玩大菠萝,我被忽悠进来做肉盾,选了蛮子,从1.0开始,经历了103.105.108.2.0.2.1.这个游戏对我最大的帮助是学习了不同的技术,比如XAML.比如xcode ...

  7. eclipse技巧总结

       如果遇到错误或警告,先试试统一的方法:在problems view中,右键error或者warnning,选择quick fix serial ID并不常用,如果不实现它,eclipse会给出一 ...

  8. "此站点已经禁用应用程序"在sharepoint 2013中通过v2013部署app提示该错误

    该错误的原文是:the apps are disabled in this site 可以在yahoo或者bing上搜索这个错误,可以找到解决办法: msdn上也有该错误解决办法,但是如果搜索中文,目 ...

  9. 关于#pragma once和#ifndefine组合的区别

    最近在看duilib代码,发现头文件既有#pragma once 又有 #ifndefine...#define,忽然就觉得有点不解,因为据我所知这两者都是防止头文件二次包含的. 经过下面两位的解释后 ...

  10. C#中的interface

    接口(interface) 接口泛指实体把自己提供给外界的一种抽象化物(可以为另一实体),用以由内部操作分离出外部沟通方法,使其能被修改内部而不影响外界其他实体与其交互的方式. 接口实际上是一个约定: ...