【BZOJ3545】[ONTAK2010]Peaks

Description

在Bytemountains有N座山峰,每座山峰有他的高度h_i。有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询问从点v开始只经过困难值小于等于x的路径所能到达的山峰中第k高的山峰,如果无解输出-1。

Input

第一行三个数N,M,Q。
第二行N个数,第i个数为h_i
接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径。
接下来Q行,每行三个数v x k,表示一组询问。

Output

对于每组询问,输出一个整数表示答案。

Sample Input

10 11 4
1 2 3 4 5 6 7 8 9 10
1 4 4
2 5 3
9 8 2
7 8 10
7 1 4
6 7 1
6 4 8
2 1 5
10 8 10
3 4 7
3 4 6
1 5 2
1 5 6
1 5 8
8 9 2

Sample Output

6
1
-1
8

HINT

【数据范围】

N<=10^5, M,Q<=5*10^5,h_i,c,x<=10^9。

【BZOJ3551】[ONTAK2010]Peaks加强版

题意:同3545,强制在线

题解:3545:这道题我们很容易想到用最小生成树,然后离线来搞。将询问按照x排序,在最小生成树加边的过程中,每加一条边就把所有x小于当前边权的询问处理掉。求第k大可以用Treap搞定,将并查集合并时也将Treap进行启发式合并(把小的Treap暴力拆掉,一个一个加到大的中去),不过我有点懒得写了。

3551:既然是强制在线我们就不能用Treap搞了,但最小生成树是一定要求的。本题利用到了Kruskal重构树的性质(什么是Kurskal重构树?)

在并查集合并的时候,我们不直接令f[a]=b,而是新建一个点ext,将a和b都合并到以ext为根的并查集上,并且令ext的点权等于e(a,b)的边权,这样我们就得到了一棵Kruskal重构树,本题的Kruskal重构树如下图所示

容易发现,Kruskal重构树满足:子节点的边权一定小于父亲节点的边权。于是我们可以用倍增求出v的深度最小的、且满足边权不超过x的祖先,因此满足所有到v路径上最大边权不超过x的节点,一定就在这棵子树上,然后询问就变成了求这棵子树中的第k大。为此我们只需要用DFS序,然后就可以将求子树的第k大转变成求一段区间中的第k大,这样跑一遍主席树就行了。

再捋一下思路:先离散化(因为是10^9),在跑Kruskal,顺便建树,然后预处理倍增,求出DFS序,再预处理主席树,最后在线处理询问

由于本人比较懒我就直接用3551的代码改一改就把3545交了,但其实写一发Treap也是挺好的

至于TLE的建议写个读入优化吧,没准就AC了。

3551代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=200010;
int n,m,Q,cnt,tot,sum,H,ans;
struct edge
{
int pa,pb,len;
}p[500010];
struct node
{
int siz,ls,rs;
}s[4000000];
struct NUM
{
int num,org;
}v[maxn];
int h[maxn],f[maxn],bel[maxn],fa[maxn][20],dp[maxn][20],Log[maxn],to[maxn],next[maxn],root[maxn];
int qx[maxn],qy[maxn],qz[maxn],ql[maxn],qr[maxn],q[maxn],rx[maxn],rh[maxn],head[maxn];
bool cmp1(edge a,edge b)
{
return a.len<b.len;
}
bool cmp2(NUM a,NUM b)
{
return a.num<b.num;
}
int readin()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9'){if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
int find(int x)
{
if(f[x]!=x) f[x]=find(f[x]);
return f[x];
}
void add(int a,int b)
{
if(b==0) return ;
to[cnt]=b;
next[cnt]=head[a];
head[a]=cnt++;
}
void dfs(int x)
{
ql[x]=q[0];
if(head[x]==-1) q[++q[0]]=x;
for(int i=head[x];i!=-1;i=next[i]) dfs(to[i]);
qr[x]=q[0];
}
void RMQ()
{
int i,j;
for(i=2;i<=2*n;i++) Log[i]=Log[i>>1]+1;
for(j=1;(1<<j)<=2*n;j++)
for(i=1;i+(1<<j)-1<=2*n;i++)
fa[i][j]=fa[fa[i][j-1]][j-1];
}
void insert(int x,int &y,int l,int r,int pos)
{
y=++tot;
if(l==r)
{
s[y].siz=s[x].siz+1;
return ;
}
int mid=l+r>>1;
if(pos<=mid) s[y].rs=s[x].rs,insert(s[x].ls,s[y].ls,l,mid,pos);
else s[y].ls=s[x].ls,insert(s[x].rs,s[y].rs,mid+1,r,pos);
s[y].siz=s[s[y].ls].siz+s[s[y].rs].siz;
}
void query(int x,int y,int l,int r,int pos)
{
if(l==r)
{
ans=rh[l];
return ;
}
int mid=l+r>>1;
if(s[s[y].rs].siz-s[s[x].rs].siz>=pos) return query(s[x].rs,s[y].rs,mid+1,r,pos);
return query(s[x].ls,s[y].ls,l,mid,pos-s[s[y].rs].siz+s[s[x].rs].siz);
}
int main()
{
n=readin(),m=readin(),Q=readin();
memset(head,-1,sizeof(head));
int i,j,a,b,c;
for(i=1;i<=n;i++) v[i].num=readin(),v[i].org=i;
sort(v+1,v+n+1,cmp2);
rh[H]=-1;
for(i=1;i<=n;i++)
{
if(rh[H]<v[i].num) rh[++H]=v[i].num;
h[v[i].org]=H;
}
for(i=1;i<=m;i++) p[i].pa=readin(),p[i].pb=readin(),p[i].len=readin();
sort(p+1,p+m+1,cmp1);
for(i=1;i<2*n;i++) f[i]=i;
for(i=1;i<=m;i++)
{
a=find(p[i].pa),b=find(p[i].pb);
if(a!=b)
{
sum++;
add(sum+n,a),add(sum+n,b);
f[a]=f[b]=sum+n;
fa[a][0]=fa[b][0]=sum+n;
rx[sum]=p[i].len;
if(sum==n-1) break;
}
}
dfs(sum+n);
for(i=1;i<=n;i++) insert(root[i-1],root[i],1,H,h[q[i]]);
RMQ();
for(i=1;i<=Q;i++)
{
scanf("%d%d%d",&a,&b,&c);
a^=ans,b^=ans,c^=ans;
int temp=a;
for(j=Log[2*n];j>=0;j--)
if(fa[temp][j]&&rx[fa[temp][j]-n]<=b)
temp=fa[temp][j];
if(c>qr[temp]-ql[temp])
{
printf("-1\n");
ans=0;
continue;
}
query(root[ql[temp]],root[qr[temp]],1,H,c);
printf("%d\n",ans);
}
return 0;
}

【BZOJ3551】[ONTAK2010]Peaks加强版 最小生成树+DFS序+主席树的更多相关文章

  1. 2018.09.30 bzoj3551:Peaks加强版(dfs序+主席树+倍增+kruskal重构树)

    传送门 一道考察比较全面的题. 这道题又用到了熟悉的kruskal+倍增来查找询问区间的方法. 查到询问的子树之后就可以用dfs序+主席树统计答案了. 代码: #include<bits/std ...

  2. [BZOJ3551][ONTAK2010]Peaks(加强版)(Kruskal重构树,主席树)

    3551: [ONTAK2010]Peaks加强版 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 2438  Solved: 763[Submit][ ...

  3. BZOJ.3551.[ONTAK2010]Peaks加强版(Kruskal重构树 主席树)

    题目链接 \(Description\) 有n个座山,其高度为hi.有m条带权双向边连接某些山.多次询问,每次询问从v出发 只经过边权<=x的边 所能到达的山中,第K高的是多少. 强制在线. \ ...

  4. bzoj 3551 [ONTAK2010]Peaks加强版(kruskal,主席树,dfs序)

    Description [题目描述]同3545 Input 第一行三个数N,M,Q. 第二行N个数,第i个数为h_i 接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径. 接下来 ...

  5. BZOJ 3439: Kpm的MC密码 (trie+dfs序主席树)

    题意 略 分析 把串倒过来插进trietrietrie上, 那么一个串的kpmkpmkpm串就是这个串在trietrietrie上对应的结点的子树下面的所有字符串. 那么像 BZOJ 3551/354 ...

  6. 【bzoj3545/bzoj3551】[ONTAK2010]Peaks/加强版 Kruskal+树上倍增+Dfs序+主席树

    bzoj3545 题目描述 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询 ...

  7. dfs序+主席树 或者 树链剖分+主席树(没写) 或者 线段树套线段树 或者 线段树套splay 或者 线段树套树状数组 bzoj 4448

    4448: [Scoi2015]情报传递 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 588  Solved: 308[Submit][Status ...

  8. 【bzoj1803】Spoj1487 Query on a tree III DFS序+主席树

    题目描述 You are given a node-labeled rooted tree with n nodes. Define the query (x, k): Find the node w ...

  9. BZOJ 3551: [ONTAK2010]Peaks加强版 [Kruskal重构树 dfs序 主席树]

    3551: [ONTAK2010]Peaks加强版 题意:带权图,多组询问与一个点通过边权\(\le lim\)的边连通的点中点权k大值,强制在线 PoPoQQQ大爷题解传送门 说一下感受: 容易发现 ...

随机推荐

  1. iOS开发中的错误整理,导航控制器的导航栏取消系统渲染的错误

  2. Linux 克隆虚拟机引起的“Device eth0 does not seem to be present, delaying initialization”

    Linux 克隆虚拟机引起的“Device eth0 does not seem to be present, delaying initialization” 虚拟机Vmware上克隆了一个Red ...

  3. 专题实验 Statspack & 9大动态视图

    statspack 是一个DBA经常用的调优工具, 它的主要作用是, 针对数据库的不同时刻做快照, 然后来比对快照之前的差异和瓶颈, 快照可以是手动的也可以是自动的, 从 oracle 10g开始, ...

  4. r指定位置插入一列数值

    y<-1:4 data1 <-data.frame(x1=c(1,3,5,7), x2=c(2,4,6,8),x3=c(11,12,13,14),x4=c(15,16,17,18)) da ...

  5. 从jQuery谈库与框架的设计之优劣

    jQuery是业内知名的javascript框架,它的实现和设计可以说代表了javascript界最高的水平,本文试从四个方面来以jQuery为例总结库与框架设计的原则和优劣判断. 解决问题 首先请看 ...

  6. 【转】【C++】C++ 中的线程、锁和条件变量

    线程 类std::thread代表一个可执行线程,使用时必须包含头文件<thread>.std::thread可以和普通函数,匿名函数和仿函数(一个实现了operator()函数的类)一同 ...

  7. android Menu 笔记

    菜单是应用中常见的用户组件.本文介绍如何在布局文件和代码中添加menu,submenu以及在代码中添加的方法. 参考链接 https://developer.android.com/guide/top ...

  8. SimplifiedHibernate:简化了的Hibernate

    我的目的是实现下Hibernate中增删改查.缓存的核心功能.虽然基本功能实现了,但可能还有好多Bug,欢迎点评拍砖,没准能在一片谩骂声中取得意想不到的进步,:) // DatabaseAccess. ...

  9. Java进阶路线图

    第一阶段 技术名称 技术内容 J2SE(Java基础部分) Java开发前奏 计算机基本原理,Java语言发展简史以及开发环境的搭建,体验Java程序的开发,环境变量的设置,程序的执行过程,相关反编译 ...

  10. 织梦DedeCMS使用SQL批量替换文章标题内容

    在使用织梦DedeCMS的过程中,出于伪原创或者其他的原因,我们需要对文档的内容.标题.描述等等进行同义词或者其他的替换.这个就是一个简单的织梦SQL语句操作的问题,No牛网在织梦DedeCMS常用S ...