【学术篇】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 ...
随机推荐
- 6.2_springboot2.x分布式整合Dubbo
1.分布式应用 在分布式系统中,国内常用zookeeper+dubbo组合,而Spring Boot推荐使用全栈的Spring,Spring Boot+Spring Cloud. 分布式系统: 特 ...
- 41-Ubuntu-用户管理-06-su切换用户
su 切换用户 序号 命令 作用 说明 01 su - 用户名 切换用户,并且切换家目录 '-'可以切换到用户家目录,否则保持位置不变 02 exit 退出当前登录账户 返回上一级用户 图:su与ex ...
- 代码托管平台--GitHub 使用小结
一.GitHub介绍 GitHub是一个面向开源及私有软件项目的托管平台,因为只支持git作为唯一的版本库格式进行托管.在GitHub,用户可以十分轻易地找到海量的开源代码. 很多IT行业的人到求职的 ...
- composer 的安装以及一些插件的下载等
安装composer: 下载composer: curl -sS https://getcomposer.org/installer | php 将composer.phar文件移动到bin目录以便全 ...
- java中的.java和.class的区别
java文件就是这样一个未经编译的源程序,一般是给程序员看的. class文件就是被编译器编译过的java文件,通常是给计算机看的.
- 使用 SpringBoot 配置发送邮件功能
1.使用 SpringBoot 配置发送邮件功能 项目总体结构 用户表设计 SET FOREIGN_KEY_CHECKS=0; CREATE DATABASE sample; USE sample; ...
- 使用EditPlus批量修改文件编码格式
步骤一: 步骤二: 步骤三: 步骤四:
- 七牛云-C#SDK-上传-简单上传
请看系列C#-SDK-操作系列 https://i.cnblogs.com/posts?categoryid=1468598 接下来给大家分享的C#-SDK 简单上传 核心代码:有需要直接看这个,其实 ...
- php 即点即改
html代码 <td><span id="list_order">{$vo.list_order}</span> </td> < ...
- Java——Eclipse使用
从这开始使用IDE啦~ ①File → New → Java Project →填写工程名字,选择jdk版本,其他默认,单击finish. ②在Src(源文件)上鼠标右键 → new → packag ...