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,表示一组询问。v=v xor lastans,x=x xor lastans,k=k xor lastans。如果lastans=-1则不变。

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
10
9
-1

HINT

【数据范围】
N<=10^5, M,Q<=5*10^5,h_i,c,x<=10^9。

分析:
Kruskal树+主席树
一开始我以为要把所有的边都建到kruskal树上
但是边好多,而且好像办不到啊
后来仔细一想
题目要求是在<=x的边上移动

只要找到最小生成树就可以了

也许会有这样的疑问
一条边<=x
但是ta连接的两个点一定在一个联通快内了,那么x就连不上了,这怎么办呢
没有做到在所有<=x的边上移动啊

但是仔细考虑一下我们的命题
x连接的两个点已经联通了,那加不加x这条边都没有影响啊

整理一下代码思路吧:
一.如果要用数组存储主席树的话
一上来就要对高度进行离散(神烦)
二.一个很普通的kruskal构建,我这里用的是自己yy的做法
三.倍增维护爸爸和权值
**四.**dfs 这个dfs很鬼,只有是叶子结点的才能算入dfs序
五.构建主席树
因为我几乎不会主席树,所以找的网上dalao的代码(纯结构体,我喜欢)
其实就是把每个高度扔进树里,每扔一个数root+1表示时间的推移
因为我们是按照dfs序来进行的构建,所以一棵子树的root一定是一个区间
主席树节点中要记录左儿子,右儿子和树中的元素数目
六.处理询问

注意,初始ans=1

询问的处理就像线段树一样,
因为提问的是第k高,所以就是从后往前数的第k个
如果区间右儿子的值相减大于x,那我们直接进入x
否则进入左儿子,但是x的值要相应的处理

-tree[tree[y].r].sz+tree[tree[x].r].sz

tip

数组一定要开够了
主席树的空间nlogn,200000*20

这里写代码片
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>using namespace std;const int N=200005;
struct node{int x,y,v;
};
node e[500010];
struct nd{int x,y,nxt;
};
nd way[N];
int mx[N][20],lg,f[N][20];
int n,m,h[N],Q,fa[N],tot=0,st[N],in[N],out[N],cnt=0,tt,H,hh[N],root[N];
int a[N],total=0,ans=0;
struct nod{int l,r,sz;
};
nod tree[4000000];
struct point{int x,bh;
};
point po[N];void add(int u,int w)
{tot++;way[tot].x=u;way[tot].y=w;way[tot].nxt=st[u];st[u]=tot;
}int cmp2(const point &a,const point &b){return a.x<b.x;}
int cmp(const node &a,const node &b){return a.v<b.v;}int find(int a)
{if (fa[a]!=a) fa[a]=find(fa[a]);return fa[a];
}void kruskal()
{int i,j,o=0;tt=n;sort(e+1,e+1+m,cmp);for (int i=1;i<=n+n;i++) fa[i]=i; for (i=1;i<=m;i++){int f1=find(e[i].x);int f2=find(e[i].y);if (f1!=f2){fa[f1]=fa[f2]=++tt;  //并查集 f[f1][0]=f[f2][0]=tt;  //papa mx[f1][0]=mx[f2][0]=e[i].v;   //最大值 add(tt,f1);add(tt,f2);o++;}if (o==n-1) break;}
}void dfs(int x)
{in[x]=a[0];if (st[x]==0) a[++a[0]]=x;   //dfsfor (int i=st[x];i;i=way[i].nxt)dfs(way[i].y);out[x]=a[0];
}void insert(int x,int &y,int l,int r,int z)
{y=++total;   //total节点计数if (l==r){tree[y].sz=tree[x].sz+1;return;} int mid=(l+r)>>1;if (z<=mid) tree[y].r=tree[x].r,insert(tree[x].l,tree[y].l,l,mid,z);else tree[y].l=tree[x].l,insert(tree[x].r,tree[y].r,mid+1,r,z);tree[y].sz=tree[tree[y].l].sz+tree[tree[y].r].sz;
}void ask(int x,int y,int l,int r,int k)
{if (l==r) {ans=hh[l];  //山峰高度return; }int mid=(l+r)>>1;if (tree[tree[y].r].sz-tree[tree[x].r].sz>=k) return ask(tree[x].r,tree[y].r,mid+1,r,k);else return ask(tree[x].l,tree[y].l,l,mid,k-tree[tree[y].r].sz+tree[tree[x].r].sz);
//因为提问的是第k高,所以就是从后往前数的第k个
}int main()
{scanf("%d%d%d",&n,&m,&Q);for (int i=1;i<=n;i++) scanf("%d",&po[i].x),po[i].bh=i;sort(po+1,po+1+n,cmp2);H=0;hh[H]=-1;for (int i=1;i<=n;i++){if (hh[H]<po[i].x) hh[++H]=po[i].x;  //hh[H] H对应的数字 h[po[i].bh]=H;   //离散后的答案 }for (int i=1;i<=m;i++)scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].v);kruskal();lg=log(tt)/log(2);for (int i=1;i<=lg;i++)   //倍增 for (int j=1;j<=tt;j++)f[j][i]=f[f[j][i-1]][i-1],mx[j][i]=max(mx[j][i-1],mx[f[j][i-1]][i-1]);dfs(tt);for (int i=1;i<=n;i++) insert(root[i-1],root[i],1,H,h[a[i]]);  //按照dfs序添加 for (int i=1;i<=Q;i++){int u,w,z;scanf("%d%d%d",&u,&w,&z);u^=ans;w^=ans;z^=ans;int temp=u;for (int j=lg;j>=0;j--)  //找到符合条件的lca if (f[temp][j]&&mx[temp][j]<=w)  //lca<=xtemp=f[temp][j];  //temp=lca-1if (out[temp]-in[temp]<z){puts("-1");ans=0;continue;} ask(root[in[temp]],root[out[temp]],1,H,z);//一开始还在奇怪为什么不是in[temp]-1,仔细想了一下在计算lca的时候我们已经少算了一个1了 printf("%d\n",ans);}return 0;
}

转载于:https://www.cnblogs.com/wutongtong3117/p/7673373.html

bzoj3551 [ONTAK2010]Peaks加强版(Kruskal重构树+主席树)相关推荐

  1. bzoj3551 [ONTAK2010]Peaks加强版 kruskal重构树

    最大边最小,就是最小生成树,可以考虑用主席树维护father数组,但不能遍历子集查找 然后就只能牺牲一部分空间时间来多存一些东西 多存的就是边值大小顺序,本来以为是用主席树排边值,结果由于此题有2种数 ...

  2. #3551. [ONTAK2010]Peaks加强版(kruskal 重构树 + 主席树)

    #3551. [ONTAK2010]Peaks加强版 我们要求从一个点出发经过困难值小于等于xxx的路径所能到达的山峰中第kkk高的是什么. 考虑按照边权升序,建议kruskalkruskalkrus ...

  3. [ONTAK2010] Peaks加强版 (kruskal重构树+主席树+倍增)

    Peaks description solution code description 在Bytemountains有N座山峰,每座山峰有他的高度h_i 有些山峰之间有双向道路相连,共M条路径,每条路 ...

  4. LOJ.2865.[IOI2018]狼人(Kruskal重构树 主席树)

    LOJ 洛谷 这题不就是Peaks(加强版)或者归程么..这算是\(IOI2018\)撞上\(NOI2018\)的题了? \(Kruskal\)重构树(具体是所有点按从小到大/从大到小的顺序,依次加入 ...

  5. Peaks加强版 黑暗爆炸 - 3551 Kruskal重构树 + 主席树

    传送门 文章目录 题意: 思路: 题意: 给你一张图,有nnn个山峰,每个山峰高度为hih_ihi​,有mmm条边,每条边有个难度值wiw_iwi​,现在有qqq个询问,每次询问给定一个山峰vvv,问 ...

  6. P4197-Peaks【Kruskal重构树,主席树】

    正题 题目链接:https://www.luogu.com.cn/problem/P4197 题目大意 nnn个点的一张无向图,每个点有一个hih_ihi​,边有权值. qqq次询问从vvv出发不走权 ...

  7. P4899-[IOI2018]werewolf 狼人【Kruskal重构树,主席树】

    正题 题目链接:https://www.luogu.com.cn/problem/P4899 题目大意 nnn个点的一张无向图,每次询问(s,t,l,r)(s,t,l,r)(s,t,l,r)表示询问能 ...

  8. P4899 [IOI2018] werewolf 狼人(kruskal 重构树 + 主席树)

    P4899 [IOI2018] werewolf 狼人 给定一个有nnn个点mmm条边的无向图,有QQQ个询问 每次输入S,E,L,RS, E, L, RS,E,L,R,表示你在SSS点出发,要到EE ...

  9. 牛客 - 牛半仙的妹子图(并查集+bitset/克鲁斯卡尔重构树+主席树)

    题目链接:点击查看 题目大意:给出一个由 n 个点和 m 条边组成的连通图,每个点都有一种颜色,每条边都有一个权值,现在规定一个起点 st,再给出 q 次询问,每次询问给出区间 [ l , r ] , ...

  10. bzoj3551: [ONTAK2010]Peaks加强版

    很明显只有最小生成树里面的点有用 我会一个离线的做法,把询问边长排序,逐步合并树,启发式合并splay 在线怎么做呢? 考虑合并出最小生成树的过程,两点合并是并不是一边连向一边而是建出新点,并将新点连 ...

最新文章

  1. mysql集群的使用与简单测试
  2. jsp 使用base标签 没有作用_终于弄明白衣服上,使用前请移除的标签到底是什么,起什么作用...
  3. Spring Roo开发初评
  4. 一个稍微复杂的VTK程序
  5. LVS DR模式搭建,keepalived + LVS
  6. 举例说明string类和stringbuffer类的区别_String,StringBuilder,StringBuffer的区别
  7. 从实战到原理,线程池的各类使用场景整合
  8. EXTJS 双层表头 记录
  9. 部署 Job (第三部分)
  10. 将springboot打包成的jar文件做成windows服务
  11. 【利用FLASH制作交互式课件】
  12. 网站怎么添加ico小图标
  13. 用艾宾浩斯曲线记忆周期来背单词是否有理论依据?
  14. 0/1背包问题 - 如何理解 解空间
  15. 服务器主机是什么系统版本,服务器主机是什么系统
  16. 为什么它有典型FaaS能力,却是非典型FaaS架构?
  17. Matplotlib之条形图绘制
  18. php 导入excel 日期格式值处理
  19. English:现在分词和过去分词的用法
  20. 错题整理:作业100题(一)

热门文章

  1. 4.Mongodb之js脚本
  2. 【备忘录】word利用mathtype进行公式分章节编号和引用
  3. 线程池及其实现文章一
  4. centos nginx php5.3,centos6.2+nginx-1.2.3+php-5.3.17装配脚本
  5. C#中 构造函数的执行
  6. linux 线程同步与互斥:互斥锁 多线程访问共享资源时,使用互斥锁进行控制
  7. CAS单点登陆,URL多出个参数jsessionid导致登陆失败问题
  8. string.split方法 保留分隔符_白月黑说什么是对象的方法?以及string类型数据对象的常见方法解析...
  9. MyBatis的XML配置文件(一)
  10. 安装Fiddler后无法上网的问题