这是学完主席树去写的第二道题_(:з」∠)_
之前用树上莫队水过了COT2...
其实COT也可以用树上莫队水过去不过好像复杂度要带个log还是怎么样可能会被卡常数..
那就orz主席吧.... 写了一发然后非常快速的WA掉了...
然鹅bzoj(luogu)搞成了强制在线, 那就真的不能orz莫队智能orz主席了...
结果在luogu写了一发交上去全RE... 然后发现讨论区一帮子病友...
但是根据他们的心得改一波还是RE啊... 后来发现是自己脑抽参数传错了... 于是就WA呗, 那么一xor lastans的点值就很可能不合法就GG咯~

通过写的第一道主席树, 可以知道其实就是维护一个可减的线段树前缀和.
话说本来是想写写主席树的但是构思了一下发现实在讲不清楚那就省了吧OvO
所以搬到树上用一波树上差分就ok了.. 我们令第$i$棵主席树储存$1\sim i$这条链的前缀和, 那么

\[
ans_{x,y}=sum_x+sum_y-sum_{lca(x,y)}-sum_{fa_{lca(x,y)}}
\]

那就跟平常的主席树差不多咯...

代码:

#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
vector<int> vec;
const int N=222222;
const int L=18;
inline int gn(int a=0,char c=0,int f=1){
for(;(c<'0'||c>'9')&&c!='-';c=getchar()); if(c=='-') f=-1,c=getchar();
for(;c>='0'&&c<='9';c=getchar()) a=a*10+c-'0'; return a*f;
}struct node{
int sum,l,r;
}t[N<<5]; int tot;
void inser(int num,int &x,int l,int r){
t[++tot]=t[x]; x=tot; ++t[x].sum;
if(l==r) return; int mid=(l+r)>>1;
if(num<=mid) inser(num,t[x].l,l,mid);
else inser(num,t[x].r,mid+1,r);
}
struct edge{
int to,next;
}e[N<<1]; int v[N],tt,n,q;
int lca[N][L],d[N],a[N],rt[N];
inline void buildedge(int x,int y){
e[++tt].to=y; e[tt].next=v[x]; v[x]=tt;
e[++tt].to=x; e[tt].next=v[y]; v[y]=tt;
}
void dfs(int x){
rt[x]=rt[lca[x][0]];
inser(lower_bound(vec.begin(),vec.end(),a[x])-vec.begin()+1,rt[x],1,n);
for(int i=1;i<L;++i) lca[x][i]=lca[lca[x][i-1]][i-1];
for(int i=v[x];i;i=e[i].next){
int y=e[i].to;
if(lca[x][0]!=y){
lca[y][0]=x;
d[y]=d[x]+1;
dfs(y);
}
}
}
//luogu的COT强制在线所以就不能用tarjan了...
inline int querylca(int x,int y){
if(d[x]<d[y]) swap(x,y);
int k=d[x]-d[y];
for(int i=L-1;i>=0;--i)
if(k&(1<<i))
x=lca[x][i];
if(x==y) return x;
for(int i=L-1;i>=0;--i)
if(lca[x][i]!=lca[y][i])
x=lca[x][i],y=lca[y][i];
return lca[x][0];
}
int query(int x,int y,int fa,int fafa,int k,int l,int r){
if(l==r) return l; int mid=(l+r)>>1;
int sum=t[t[x].l].sum+t[t[y].l].sum-t[t[fa].l].sum-t[t[fafa].l].sum;
if(k<=sum) return query(t[x].l,t[y].l,t[fa].l,t[fafa].l,k,l,mid);
return query(t[x].r,t[y].r,t[fa].r,t[fafa].r,k-sum,mid+1,r);
}
int main(){
n=gn(),q=gn();
for(int i=1;i<=n;++i) a[i]=gn(),vec.push_back(a[i]);
sort(vec.begin(),vec.end()); vec.erase(unique(vec.begin(),vec.end()),vec.end());
for(int i=1;i<n;++i){int x=gn(),y=gn(); buildedge(x,y);} d[1]=1; dfs(1);
for(int i=1;i<=q;++i){
int x=gn(),y=gn(),k=gn(),fa=querylca(x,y);
printf("%d\n",vec[query(rt[x],rt[y],rt[fa],rt[lca[fa][0]],k,1,n)-1]);
//对就介个地方, 我脑抽忘了fa和lca[fa][0]也要套rt[], 然后就WA来RE去的..
}
}

非常遗憾的错过了1A的机会...
我还是太弱了...

【学术篇】SPOJ COT 树上主席树的更多相关文章

  1. Count on a tree SPOJ - COT (主席树,LCA)

    You are given a tree with N nodes. The tree nodes are numbered from 1 to N. Each node has an integer ...

  2. SPOJ COT Count on a tree(树上主席树 + LCA 求点第k小)题解

    题意:n个点的树,每个点有权值,问你u~v路径第k小的点的权值是? 思路: 树上主席树就是每个点建一棵权值线段树,具体看JQ博客,LCA用倍增logn求出,具体原理看这里 树上主席树我每个点的存的是点 ...

  3. p3302 [SDOI2013]森林(树上主席树+启发式合并)

    对着题目yy了一天加上看了一中午题解,终于搞明白了我太弱了 连边就是合并线段树,把小的集合合并到大的上,可以保证规模至少增加一半,复杂度可以是\(O(logn)\) 合并的时候暴力dfs修改倍增数组和 ...

  4. 【洛谷2633】Count on a tree(树上主席树)

    点此看题面 大致题意: 给你一棵树,每次问你两点之间第\(k\)小的点权,强制在线. 主席树 这种题目强制在线一般就是数据结构了. 而看到区间第\(k\)小,很容易就能想到主席树. 至少不会有人想到树 ...

  5. Count on a tree 树上主席树

    Count on a tree 树上主席树 给\(n\)个树,每个点有点权,每次询问\(u,v\)路径上第\(k\)小点权,强制在线 求解区间静态第\(k\)小即用主席树. 树上主席树类似于区间上主席 ...

  6. [CSP-S模拟测试]:e(树上主席树)

    题目传送门(内部题66) 输入格式 第一行,一个正整数$n$,一个自然数$q$,一个整数$type$.第二行,$n$个正整数,代表$a_i$.接下来$n-1$行,每行两个正整数$u$.$v$,代表树中 ...

  7. bzoj3123 [Sdoi2013]森林 树上主席树+启发式合并

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3123 题解 如果是静态的查询操作,那么就是直接树上主席树的板子. 但是我们现在有了一个连接两棵 ...

  8. Count on a tree(SPOJ COT + 树上第k大 + 主席树 + LCA)

    题目链接:https://www.spoj.com/problems/COT/en/ 题目: 题意: 给你一棵有n个节点的树,求节点u到节点v这条链上的第k大. 思路: 我们首先用dfs进行建题目给的 ...

  9. BZOJ 2588: Spoj 10628. Count on a tree [树上主席树]

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 5217  Solved: 1233 ...

随机推荐

  1. python类的实例方法、静态方法和类方法区别及其应用场景

    https://blog.csdn.net/helloxiaozhe/article/details/79940321 普通实例方法,第一个参数需要是self,它表示一个具体的实例本身. 如果用了st ...

  2. 剑指offer——56在排序数组中查找数字

    题目描述 统计一个数字在排序数组中出现的次数.   题解: 使用二分法找到数k然后向前找到第一个k,向后找到最后一个k,即可知道有几个k了 但一旦n个数都是k时,这个方法跟从头遍历没区别,都是O(N) ...

  3. LitJson使用中的一些问题

    http://blog.csdn.net/n5/article/details/45030063

  4. 人人开源打包jar

    先在renren-security执行mvn clean install 再到renren-admin目录下,执行mvn clean package,就可以打成renren-admin.jar 如果想 ...

  5. centos7简单安装配置mariadb

    CentOS 7下yum安装MariaDB yum install mariadb mariadb-server systemctl start mariadb #启动mariadb systemct ...

  6. 使用SpringMVC<mvc:view-controller/>标签时踩的一个坑

    <mvc:view-controller>标签 如果我们有些请求只是想跳转页面,不需要来后台处理什么逻辑,我们无法在Action中写一个空方法来跳转,直接在中配置一个如下的视图跳转控制器即 ...

  7. Hadoop–TaskTracker 相关

    TaskTracker 是Hadoop集群中运行于各个节点上的服务.他是JobTracker和Task之间的"通信桥梁".一方面它从JobTracker端接受并执行各种命令:比如运 ...

  8. CAS -- ABA问题的解决方案

    我们现在来说什么是ABA问题.假设内存中有一个值为A的变量,存储在地址V中. 此时有三个线程想使用CAS的方式更新这个变量的值,每个线程的执行时间有略微偏差.线程1和线程2已经获取当前值,线程3还未获 ...

  9. PHP之区域块链

    搭建一个最简单的区块链吧.代码简单易懂. <?php //区域块链 //block 区块 // chain 链 //data  //之前区块的has值 //自己的has值 : 他是由存储在区块链 ...

  10. 解决MySQL登录密码正确却提示错误-1045的方法

    MySQL密码正确却无法本地登录-1045 Access denied for user 'root'@'localhost' (using password:YES MySQL密码正确却无法本地登录 ...