【学术篇】SPOJ COT 树上主席树
这是学完主席树去写的第二道题_(:з」∠)_
之前用树上莫队水过了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 树上主席树的更多相关文章
- 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 ...
- SPOJ COT Count on a tree(树上主席树 + LCA 求点第k小)题解
题意:n个点的树,每个点有权值,问你u~v路径第k小的点的权值是? 思路: 树上主席树就是每个点建一棵权值线段树,具体看JQ博客,LCA用倍增logn求出,具体原理看这里 树上主席树我每个点的存的是点 ...
- p3302 [SDOI2013]森林(树上主席树+启发式合并)
对着题目yy了一天加上看了一中午题解,终于搞明白了我太弱了 连边就是合并线段树,把小的集合合并到大的上,可以保证规模至少增加一半,复杂度可以是\(O(logn)\) 合并的时候暴力dfs修改倍增数组和 ...
- 【洛谷2633】Count on a tree(树上主席树)
点此看题面 大致题意: 给你一棵树,每次问你两点之间第\(k\)小的点权,强制在线. 主席树 这种题目强制在线一般就是数据结构了. 而看到区间第\(k\)小,很容易就能想到主席树. 至少不会有人想到树 ...
- Count on a tree 树上主席树
Count on a tree 树上主席树 给\(n\)个树,每个点有点权,每次询问\(u,v\)路径上第\(k\)小点权,强制在线 求解区间静态第\(k\)小即用主席树. 树上主席树类似于区间上主席 ...
- [CSP-S模拟测试]:e(树上主席树)
题目传送门(内部题66) 输入格式 第一行,一个正整数$n$,一个自然数$q$,一个整数$type$.第二行,$n$个正整数,代表$a_i$.接下来$n-1$行,每行两个正整数$u$.$v$,代表树中 ...
- bzoj3123 [Sdoi2013]森林 树上主席树+启发式合并
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3123 题解 如果是静态的查询操作,那么就是直接树上主席树的板子. 但是我们现在有了一个连接两棵 ...
- Count on a tree(SPOJ COT + 树上第k大 + 主席树 + LCA)
题目链接:https://www.spoj.com/problems/COT/en/ 题目: 题意: 给你一棵有n个节点的树,求节点u到节点v这条链上的第k大. 思路: 我们首先用dfs进行建题目给的 ...
- 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 ...
随机推荐
- webpack中代理配置(proxyTable)
注:用axios请求 1,下载axios npm i axios --save 2,在config文件下的index.js中配置代理地址 参考:https://vuejs-templates.gith ...
- JUC源码分析-集合篇(十)LinkedTransferQueue
JUC源码分析-集合篇(十)LinkedTransferQueue LinkedTransferQueue(LTQ) 相比 BlockingQueue 更进一步,生产者会一直阻塞直到所添加到队列的元素 ...
- java-day21
# DQL:查询语句 1. 排序查询 * 语法:order by 子句 * order by 排序字段1 排序方式1 , 排序字段2 排序方式2... ...
- 2018-6-17-win10-UWP-全屏
title author date CreateTime categories win10 UWP 全屏 lindexi 2018-06-17 17:51:19 +0800 2018-2-13 17: ...
- 标准 IO 测试 可以打开多少流
#include <stdio.h> #include <string.h> #include <errno.h> //trerror(errno) int mai ...
- cookie、session、sessionStorage和localStorage
摘抄并整理后查 cookie 和 session 一般用来跟踪浏览器的用户身份 Session的存储方式 1. 使用cookie:保存 session id 的方式可以采用 cookie,这样在交互过 ...
- vue 外卖app(3) 利用slot分发内容
1. 增加一个HeaderTop.vue <template> <header class="header"> <slot name="le ...
- docker 命令操作
1.停止所有的container,这样才能够删除其中的images: docker stop $(docker ps -a -q) 如果想要删除所有container的话再加一个指令: docker ...
- select 可输入的下拉框
<!DOCTYPE html> <html> <head> <title></title> <meta charset="U ...
- MongoDB启动时遇到的问题
问题一:child process failed, exited with error number 100 原因分析:100是锁了 解决办法:#cd /usr/local/mongodb/data ...