Description

【题目描述】同3545

Input

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

Output

同3545

【思路】

Kruskal+主席树+dfs序

一个叫kruskal重构树的方法QWQ。在kruskal合并子树的时候新建一个ext结点,然后让它成为两棵子树公共的根,赋边权为权值。

新建成的树的性质:

对于一个询问,我们找到v的点权值不超过x的最小祖先,以该祖先为根的子树中所有的点与v都满足条件,然后就是在一个子树中找到第k大的问题,可以基于dfs序建主席树处理。

【代码】

 #include<cstdlib>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define FOR(a,b,c) for(int a=(b);a<=(c);a++)
using namespace std; typedef long long ll;
const int N = ;
const int M = ;
const int D = ; struct Edge {
int u,v,w;
bool operator < (const Edge& rhs) const {
return w<rhs.w;
}
};
struct LEdge { int v,nxt;
};
struct Tnode{
int lc,rc,sum;
}T[M]; ll read() {
char c=getchar();
ll f=,x=;
while(!isdigit(c)) {
if(c=='-') f=-; c=getchar();
}
while(isdigit(c))
x=x*+c-'',c=getchar();
return x*f;
} int n,m,q,sz,tot,dfsc;
int hash[N],h[N],rt[N],val[N],bin[N];
int p[N],dep[N],fa[N][D],mx[N][D],L[N],R[N]; Edge es[N<<]; LEdge e[N<<];
int en=-,front[N];
void adde(int u,int v)
{
en++; e[en].v=v; e[en].nxt=front[u]; front[u]=en;
}
int ifind(int u)
{
return u==p[u]? u: p[u]=ifind(p[u]);
}
void update(int l,int r,int x,int& y,int num)
{
T[y=++sz]=T[x];
T[y].sum++;
if(l>=r) return ;
int mid=(l+r)>>;
if(num<=mid) update(l,mid,T[x].lc,T[y].lc,num);
else update(mid+,r,T[x].rc,T[y].rc,num);
}
int query(int l,int r,int a,int b,int rk)
{
int mid=(l+r)>>;
if(l>=r) return mid;
int now=T[T[b].rc].sum-T[T[a].rc].sum;
if(rk<=now) return query(mid+,r,T[a].rc,T[b].rc,rk);
else return query(l,mid,T[a].lc,T[b].lc,rk-now);
}
void dfs(int u)
{
L[u]=++dfsc;
update(,tot,rt[L[u]-],rt[L[u]],h[u]);
FOR(i,,D-) {
fa[u][i]=fa[fa[u][i-]][i-];
mx[u][i]=max(mx[u][i-],mx[fa[u][i-]][i-]);
}
for(int i=front[u];i>=;i=e[i].nxt) {
int v=e[i].v;
dep[v]=dep[u]+,
dfs(v);
}
R[u]=dfsc;
}
int find_root(int u,int x)
{
for(int i=D-;i>=;i--)
if(fa[u][i] && mx[u][i]<=x)
u=fa[u][i];
return u;
} int main()
{
//reopen("in.in","r",stdin);
//freopen("out.out","w",stdout); memset(front,-,sizeof(front));
n=read(),m=read(),q=read();
FOR(i,,n) h[i]=read(),hash[i]=h[i];
int u,v,w,x,k,ans=;
FOR(i,,m) {
u=read(),v=read(),w=read();
es[i]=(Edge){u,v,w};
} FOR(i,,*n) p[i]=i;
sort(hash+,hash+n+);
tot=unique(hash+,hash+n+)-hash-;
FOR(i,,n)
h[i]=lower_bound(hash+,hash+tot+,h[i])-hash; sort(es+,es+m+);
FOR(i,,m) {
Edge e=es[i];
int x=ifind(e.u),y=ifind(e.v);
if(x!=y) {
int ext=++n;
fa[x][]=fa[y][]=ext;
mx[x][]=mx[y][]=e.w;
p[x]=p[y]=ext;
adde(ext,x),adde(ext,y);
}
} dfs(n); FOR(i,,q) {
v=read(),x=read(),k=read();
v^=ans,x^=ans,k^=ans;
int root=find_root(v,x);
if(R[root]-L[root]+<k) puts("-1"),ans=;
else {
ans=query(,tot,rt[L[root]-],rt[R[root]],k);
if(!ans) puts("-1");
else printf("%d\n",ans=hash[ans]);
}
}
return ;
}

bzoj 3551 [ONTAK2010]Peaks加强版(kruskal,主席树,dfs序)的更多相关文章

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

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

  2. BZOJ 3551: [ONTAK2010]Peaks加强版 Kruskal重构树+dfs序+主席树+倍增

    建出来 $Kruskal$ 重构树. 将询问点向上跳到深度最小,且合法的节点上. 那么,得益于重构树优美的性质,这个最终跳到的点为根的所有子节点都可以与询问点互达. 对于子树中求点权第 $k$ 大的问 ...

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

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

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

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

  5. 【刷题】BZOJ 3551 [ONTAK2010]Peaks加强版

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

  6. bzoj 3551: [ONTAK2010]Peaks加强版

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

  7. 【BZOJ-3545&3551】Peaks&加强版 Kruskal重构树 + 主席树 + DFS序 + 倍增

    3545: [ONTAK2010]Peaks Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1202  Solved: 321[Submit][Sta ...

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

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

  9. 3551: [ONTAK2010]Peaks加强版

    3551: [ONTAK2010]Peaks加强版 https://www.lydsy.com/JudgeOnline/problem.php?id=3551 分析: kruskal重构树 +  倍增 ...

随机推荐

  1. 1045: [HAOI2008] 糖果传递 - BZOJ

    Description 有n个小朋友坐成一圈,每人有ai个糖果.每人只能给左右两人传递糖果.每人每次传递一个糖果代价为1.Input 小朋友个数n 下面n行 aiOutput 求使所有人获得均等糖果的 ...

  2. js的基本概念详解

    来自<javascript高级程序设计 第三版:作者Nicholas C. Zakas>的学习笔记(三) 如果你刚学js,想快速了解到js的基本概念,以下将会是一篇不错的引导文章: 语法 ...

  3. POJ3697+BFS+hash存边

    /* 疾速优化+hash存边 题意:给定一个包含N(1 ≤ N ≤ 10,000)个顶点的无向完全图,图中的顶点从1到N依次标号.从这个图中去掉M(0 ≤ M ≤ 1,000,000)条边,求最后与顶 ...

  4. IntelliJ Idea12 破解码与中文乱码配置

    user name:JavaDeveloper serial number:92547-KY2BB-QZ0S1-PEZCV-HUT8Q-6RYY4        会出现Ok可以点击就会将软件 安装后, ...

  5. ERDAS IMAGINE 9.2安装破解方法

    Install the application. Copy the license.dat and ERDAS.exe to C:\Program Files\Leica Geosystems\Sha ...

  6. WCF的通信

    [ServiceContract]    public interface IContractDemoOne    {        [OperationContract(IsOneWay=true) ...

  7. Android 签名(7)签名常见问题,debug签名和release签名的区别等

    一般在安装时提示出错:INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES 1) 两个应用,名字相同,签名不同 2) 升级时前一版本签名,后一版本没签名 3) ...

  8. Ubuntu12.04下arm交叉编译环境的建立

    http://blog.csdn.net/heyangya2009/article/details/5424376 备注:ubuntu12.04+Android+Real6410 在主机上用来编译其他 ...

  9. sublime text 2 配置文件

    安装好 sublime text 2后不进行任何设置,如果允许 sublime text 2 软件的话,会在以下目录自动生成一个 sublime text 2 的文件夹,这个文件夹是用来放配置文件的, ...

  10. javascript 一些需要知道的东西

    这里我直接贴出代码,注释已经补全,欢迎指正: <script type="text/javascript"> /** 1,js中一切皆是对象,函数也是, 2,当定义变量 ...