按Dfs序逐个插入点,建立可持久化线段树,每次查询即可,具体详见代码。

不知道为什么,代码慢的要死,,

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <vector> using namespace std; template<const int _n,const int _m>
struct Edge
{
struct Edge_base { int to,next; }e[_m];
int cnt,p[_n];
Edge() { clear(); }
void insert(const int x,const int y)
{ e[++cnt].to=y; e[cnt].next=p[x]; p[x]=cnt; return ; }
int start(const int x) { return p[x]; }
void clear() { cnt=,memset(p,,sizeof(p)); }
Edge_base& operator[](const int x) { return e[x]; }
}; Edge<,> e;
vector<int> vec;
int n,q,tot,cnt;
int a[],root[],Left[],Right[];
int val[],f[][],depth[],lg2[]; void Init()
{
for(int j=;(<<j)<=n;++j)
for(int i=;i<=n;++i)
f[i][j]=f[f[i][j-]][j-];
for(int i=;i<=n;++i)lg2[i]=lg2[i>>]+;
return ;
} int Lca(int A,int B)
{
int i,j;
if(depth[A]<depth[B])swap(A,B); j=lg2[depth[A]]; for(i=j;i>=;--i)
{
if(depth[A]-(<<i)>=depth[B])A=f[A][i];
} if(A==B)return A; for(i=j;i>=;--i)
{
if(f[A][i] && f[A][i]!=f[B][i])
A=f[A][i],B=f[B][i];
}
return f[A][];
} void Insert(const int l,const int r,const int root_l,int& root_r,const int d)
{
val[root_r=++tot]=val[root_l]+;
if(l==r)return ; int mid=l+((r-l)>>);
if(d<=mid)
{
Right[root_r]=Right[root_l];
Insert(l,mid,Left[root_l],Left[root_r],d);
}
else
{
Left[root_r]=Left[root_l];
Insert(mid+,r,Right[root_l],Right[root_r],d);
} return ;
} void Dfs(const int S,const int fa)
{
depth[S]=depth[fa]+;
f[S][]=fa; a[S]=lower_bound(vec.begin(),vec.end(),a[S])-vec.begin()+;
Insert(,vec.size(),root[fa],root[S],a[S]); for(int i=e.start(S);i;i=e[i].next)
{
if(e[i].to==fa)continue;
Dfs(e[i].to,S);
}
} int kth(int l,int r,int r1,int r2,int r3,int r4,int d)
{
while(true)
{
if(l==r)return l;
int mid=l+((r-l)>>),temp;
temp=val[Left[r1]]+val[Left[r2]]-val[Left[r3]]-val[Left[r4]];
if(temp>=d)r=mid,r1=Left[r1],r2=Left[r2],r3=Left[r3],r4=Left[r4];
else l=mid+,r1=Right[r1],r2=Right[r2],r3=Right[r3],r4=Right[r4],d=d-temp;
}
return ;
} int main()
{
//freopen("in","r",stdin); int i,x,y,op; vec.resize();
scanf("%d%d",&n,&q); for(i=;i<=n;++i)
scanf("%d",&a[i]),vec.push_back(a[i]); sort(vec.begin(),vec.end());
vec.erase(unique(vec.begin(),vec.end()),vec.end()); for(i=;i<n;++i)
{
scanf("%d%d",&x,&y);
e.insert(x,y);
e.insert(y,x);
} Dfs(,);
Init(); for(i=;i<=q;++i)
{
scanf("%d%d%d",&op,&x,&y);
int temp=Lca(x,y),temp1;
if(op==)
temp1=kth(,vec.size(),
root[x],root[y],
root[temp],root[f[temp][]],);
else if(op==)
temp1=kth(,vec.size(),
root[x],root[y],
root[temp],root[f[temp][]],
depth[x]+depth[y]-(depth[temp]<<)+);
else temp1=kth(,vec.size(),
root[x],root[y],
root[temp],root[f[temp][]],
((depth[x]+depth[y]-(depth[temp]<<)+)>>)+); printf("%d\n",vec[temp1-]);
} return ;
}

[TS-A1505] [清橙2013中国国家集训队第二次作业] 树 [可持久化线段树,求树上路径第k大]的更多相关文章

  1. [tsA1490][2013中国国家集训队第二次作业]osu![概率dp+线段树+矩阵乘法]

    这样的题解只能舔题解了,,,qaq 清橙资料里有.. #include <iostream> #include <cstdio> #include <cstdlib> ...

  2. [tsA1491][2013中国国家集训队第二次作业]家族[并查集]

    m方枚举,并查集O(1)维护,傻逼题,,被自己吓死搞成神题了... #include <bits/stdc++.h> using namespace std; struct tri { i ...

  3. [TS-A1489][2013中国国家集训队第二次作业]抽奖[概率dp]

    概率dp第一题,开始根本没搞懂,后来看了09年汤可因论文才基本搞懂,关键就是递推的时候做差比较一下,考虑新加入的情况对期望值的贡献,然后推推公式(好像还是不太会推qaq...) #include &l ...

  4. [TS-A1488][2013中国国家集训队第二次作业]魔法波[高斯消元]

    暴力直接解异或方程组,O(n^6)无法接受,那么我们考虑把格子分块,横着和竖着分别分为互不影响的块,这样因为障碍物最多不超过200个,那么块的个数最多为2*(800+200)=2000个,最后用bit ...

  5. [TS-A1487][2013中国国家集训队第二次作业]分配游戏[二分]

    根据题意,设$3n$次比较中胜了$w$次,负了$l$次,平了$d$次,所有场次中胜了$W$次,负了$L$次,平了$D$次.如果一场赢了,那么$w-l$就会$+1$,相同地,$W-L$也会$+1$:如果 ...

  6. [TS-A1486][2013中国国家集训队第二次作业]树[树的重心,点分治]

    首先考虑暴力,可以枚举每两个点求lca进行计算,复杂度O(n^3logn),再考虑如果枚举每个点作为lca去枚举这个点的子树中的点复杂度会大幅下降,如果我们将每个点递归考虑,每次计算过这个点就把这个点 ...

  7. < < < 2013年国家集训队作业 > > >

    完成题数/总题数:  道/37道 1.  A1504. Book(王迪): 数论+贪心   ★★☆        2013中国国家集训队第二次作业 2.  A1505. 树(张闻涛): 倍增LCA+可 ...

  8. Tsinsen A1505. 树(张闻涛) 倍增LCA,可持久化线段树,DFS序

    题目:http://www.tsinsen.com/A1505 A1505. 树(张闻涛) 时间限制:1.0s   内存限制:512.0MB    总提交次数:196   AC次数:65   平均分: ...

  9. [BZOJ 3123] [SDOI 2013]森林(可持久化线段树+并查集+启发式合并)

    [BZOJ 3123] [SDOI 2013]森林(可持久化线段树+启发式合并) 题面 给出一个n个节点m条边的森林,每个节点都有一个权值.有两种操作: Q x y k查询点x到点y路径上所有的权值中 ...

随机推荐

  1. JZOJ 1667 ( bzoj 1801 ) [ AHOI 2009 ] 中国象棋 —— DP

    题目:https://jzoj.net/senior/#main/show/1667 首先,一行.一列最多只有 2 个炮: 所以记录一下之前有多少行有 0/1/2 个炮,转移即可: 注意取模!小心在某 ...

  2. java SWing事件调用的两种机制

      Java(91)  /** * java swing中事件调用的两种机制: * (一)响应机制 * (二)回调机制 */ package test; import java.awt.*; impo ...

  3. bzoj1106

    模拟+树状数组 先开始以为是先删距离最小的,这样可以减小上下的距离,然后觉得很难写,看码长很短,就看了题解,结果很奥妙 我们只考虑两种元素,就是如果像-a-b-a-b-这样的肯定得交换,如果像-a-b ...

  4. nova service-list for juno kilo,liberty openstack

  5. STM32:SWD下载方式

    最近没事干做了个STM32小板子,芯片是STM32VBT6,下载方式用的SWD,比JTAG节省空间 我用了五根线,3.3V,GND,RESET,SWDIO,SWCLK, JTAG 接口pin map: ...

  6. Spark SQL 操作Hive 数据

    Spark 2.0以前版本:val sparkConf = new SparkConf().setAppName("soyo")    val spark = new SparkC ...

  7. App设计师常用的10大网页和工具大盘点

    1.Adobe Photoshop 老牌的设计工具,不用解释 2.Adobe Illustrator 同上,不解释 3.Balsamiq Mockup 网址:http://balsamiq.com/ ...

  8. 过河 2005年NOIP全国联赛提高组(离散化+dp)

    1105 过河 2005年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond       题目描述 Description 在河上有一 ...

  9. go 学习成长之路

    一.go的搭建 二.初识go 三.混个脸熟--go 四.go的语言结构 五.go的常量与变量 六.go基础数据类型 七.go 条件语句 八.go 运算符 九.go条件语句switch 十.go循环语句 ...

  10. 326 Power of Three 3的幂

    给出一个整数,写一个函数来确定这个数是不是3的一个幂.后续挑战:你能不使用循环或者递归完成本题吗? 详见:https://leetcode.com/problems/power-of-three/de ...