[CSP-S模拟测试]:树(树上上升序列+主席树+线段树)
题目传送门(内部题78)
输入格式
第一行输入两个整数$n,q$,表示节点数和询问数。
第二行输入$n$个整数$w_i$,表示第$i$个点的智商。
第三行至第$n+1$行每行输入两个数$x,y$,表示树上一条边。
第$n+2$行至第$n+q+1$行每行三个数$u,v,c$表示一次探究。(保证$v$是$u$的祖先)
输出格式
输出$q$行,每行两个数表示探究过程中$cwystc$需要努力学习的次数。
样例
见下发文件
数据范围与提示
对于$10\%$的数据:$n\leqslant 1,000$
对于另外$30\%$的数据:家谱树为一条链
对于$100\%$的数据:$n,q,w_i,c\leqslant 100,000$
题解
转化一下题意,就是让我们求从$u$到$v$的上升序列长度(注意这里的上升序列是指碰见比它大的就选中,而不是最长上升子序列)。
剩下就是码力问题了……
我可能打的比较麻烦,用了主席树和线段树优化……
时间复杂度:$\Theta(n\log n)$。
期望得分:$100$分。
实际得分:$100$分。
代码时刻
#include<bits/stdc++.h>
#define L(x) x<<1
#define R(x) x<<1|1
using namespace std;
struct rec{int nxt,to;}e[200000];
int head[100001],cnt;
int n,q;
int w[100001];
int son[100001],size[100001],top[100001],fa[100001],dfn[100001],rk[100001],tim,root[5000001],lson[5000001],rson[5000001],num[5000001],tot;
int tr[400001];
void add(int x,int y)
{
e[++cnt].nxt=head[x];
e[cnt].to=y;
head[x]=cnt;
}
void pushups(int x){num[x]=num[lson[x]]+num[rson[x]];}
void pushupm(int x){tr[x]=max(tr[L(x)],tr[R(x)]);}
void build(int x,int l,int r)
{
if(l==r){tr[x]=w[rk[l]];return;}
int mid=(l+r)>>1;
build(L(x),l,mid);
build(R(x),mid+1,r);
pushupm(x);
}
void adds(int &x,int f,int l,int r,int w)
{
if(!x)x=++tot;
if(l==r){num[x]=1;return;}
int mid=(l+r)>>1;
if(w<=mid)
{
rson[x]=rson[f];
adds(lson[x],lson[f],l,mid,w);
}
else adds(rson[x],rson[f],mid+1,r,w);
pushups(x);
}
int asks(int x,int l,int r,int w)
{
if(!x)return 0;
if(w<=l)return num[x];
int mid=(l+r)>>1;
if(w<=mid)return asks(lson[x],l,mid,w)+num[rson[x]];
else return asks(rson[x],mid+1,r,w);
}
int askm(int x,int l,int r,int L,int R)
{
if(r<L||R<l)return 0;
if(L<=l&&r<=R)return tr[x];
int mid=(l+r)>>1;
return max(askm(L(x),l,mid,L,R),askm(R(x),mid+1,r,L,R));
}
void dfs(int x,int f)
{
size[x]=1;
top[x]=x;
adds(root[x],root[f],0,1000000,w[x]);
for(int i=head[x];i;i=e[i].nxt)
{
if(size[e[i].to])continue;
fa[e[i].to]=x;
dfs(e[i].to,x);
size[x]+=size[e[i].to];
if(size[son[x]]<size[e[i].to])son[x]=e[i].to;
}
}
void dfs(int x)
{
dfn[x]=++tim;
rk[tim]=x;
if(son[x])
{
top[son[x]]=top[x];
dfs(son[x]);
}
for(int i=head[x];i;i=e[i].nxt)
if(!dfn[e[i].to])dfs(e[i].to);
}
int query(int x,int y,int c)
{
int now=top[x],mx=c;
int res=asks(root[x],0,1000000,c+1);
while(now!=top[y])
{
mx=max(mx,askm(1,1,n,dfn[now],dfn[x]));
x=fa[now];
now=top[x];
}
mx=max(mx,askm(1,1,n,dfn[y],dfn[x]));
res-=asks(root[fa[y]],0,1000000,mx+1);
return res;
}
int main()
{
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++)scanf("%d",&w[i]);
for(int i=1;i<n;i++)
{
int u,v;
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
dfs(1,0);
dfs(1);
build(1,1,n);
while(q--)
{
int u,v,c;
scanf("%d%d%d",&u,&v,&c);
printf("%d\n",query(u,v,c));
}
return 0;
}
rp++
[CSP-S模拟测试]:树(树上上升序列+主席树+线段树)的更多相关文章
- [CSP-S模拟测试]:地理课(并查集+线段树分治)
题目传送门(内部题146) 输入格式 从$geography.in$读入数据. 第一行两个数$n,m$,表示有$n$个点,$m$个时刻.接下来$m$行每行三个数,要么是$1\ u\ v$,要么是$2\ ...
- [CSP-S模拟测试]:队长快跑(DP+离散化+线段树)
题目背景 传说中,在远古时代,巨龙大$Y$将$P$国的镇国之宝窃走并藏在了其巢穴中,这吸引着整个$P$国的所有冒险家前去夺回,尤其是皇家卫士队的队长小$W$.在$P$国量子科技实验室的帮助下,队长小$ ...
- BZOJ_1858_[Scoi2010]序列操作_线段树
BZOJ_1858_[Scoi2010]序列操作_线段树 Description lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询 ...
- 【BZOJ1858】序列操作(线段树)
[BZOJ1858]序列操作(线段树) 题面 BZOJ 题解 这题思路很简单,细节很烦,很码 维护区间翻转和区间赋值标记 当打到区间赋值标记时直接覆盖掉翻转标记 下放标记的时候先放赋值标记再放翻转标记 ...
- 【BZOJ2962】序列操作(线段树)
[BZOJ2962]序列操作(线段树) 题面 BZOJ 题解 设\(s[i]\)表示区间内选择\(i\)个数的乘积的和 考虑如何向上合并? \(s[k]=\sum_{i=0}^klson.s[i]*r ...
- HDU-6704 K-th occurrence (后缀自动机father树上倍增建权值线段树合并)
layout: post title: HDU-6704 K-th occurrence (后缀自动机father树上倍增建权值线段树合并) author: "luowentaoaa&quo ...
- P2023 [AHOI2009]维护序列 题解(线段树)
题目链接 P2023 [AHOI2009]维护序列 解题思路 线段树板子.不难,但是...有坑.坑有多深?一页\(WA\). 由于乘法可能乘\(k=0\),我这种做法可能会使结果产生负数.于是就有了这 ...
- Dynamic Rankings(树状数组套权值线段树)
Dynamic Rankings(树状数组套权值线段树) 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[ ...
- BZOJ4860 BJOI2017 树的难题 点分治、线段树合并
传送门 只会线段树……关于单调队列的解法可以去看“重建计划”一题. 看到路径长度$\in [L,R]$考虑点分治.可以知道,在当前分治中心向其他点的路径中,始边(也就是分治中心到对应子树的根的那一条边 ...
- BZOJ2141排队——树状数组套权值线段树(带修改的主席树)
题目描述 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家 乐和和.红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们的身高有所区别 ...
随机推荐
- 手写一个IOC容器
链接:https://pan.baidu.com/s/1MhKJYamBY1ejjjhz3BKoWQ 提取码:e8on 明白什么是IOC容器: IOC(Inversion of Control,控制反 ...
- 配置NAT
NAT是将IP数据报文报头中的IP地址转换为另-一个IP地址的过程,主要用于实现内部网络(私有IP地址)访问外部网络(公有IP地址)的功能.NAT有3种类型:静态NAT.动态地址NAT以及网络地址端口 ...
- 修改SpringBoot启动时的默认Banner图案
1.在src/main/resources下新建banner.txt,在文件中加入要显示的图案即可: 2.生成图案的网站: http://patorjk.com/software/taag/ http ...
- 【JZOJ 3910】Idiot 的间谍网络
题面: Description 作为一名高级特工,Idiot 苦心经营多年,终于在敌国建立起一张共有n 名特工的庞大间谍网络. 当然,出于保密性的要求,间谍网络中的每名特工最多只会有一名直接领导.现在 ...
- 基于BufferedImage的图像滤镜演示
package chapter2; import javax.imageio.ImageIO;import javax.swing.*;import javax.swing.filechooser.F ...
- 华为云搭建windows+wordpress+xampp
1.如何将本地文件上传至华为云ECS云服务器(Windows系统) 1.1 在本地电脑上,快捷键“WIN+R"打开“运行”中输入“mstsc”,点击确定 1.2 在“远程桌面连接”框点击“ ...
- Consider defining a bean of type 'org.springframework.web.client.RestTemplate' in your configuration
https://www.cnblogs.com/EasonJim/p/7546136.html 错误如下: ERROR 31473 --- [ main] o.s.b.d.LoggingFailure ...
- C# List<Object>值拷贝
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Run ...
- 【Thinkphp5】解决模板输出时间戳自动转换为时间格式的问题
背景: 数据库存储时间为时间戳,格式为varchar,模板输出时未进行时间格式化却输出了时间格式 如下图 (数据库存储的时间戳) (页面输出的时间) (未进行格式化的时间代码) (格式化后的时间代码) ...
- HBase(一)——HBase介绍
HBase介绍 1.关系型数据库与非关系型数据库 (1)关系型数据库 关系型数据库最典型的数据机构是表,由二维表及其之间的联系所组成的一个数据组织 优点: 1.易于维护:都是使用表结构,格 ...