Description

Mr. Panda 有 N 个花园,编号从 1 到 N 。对于编号为 i 的花园,花园里只有一朵花,颜色为 ci 。花园与花园之间有道路连接(道路是双向的)。每条道路都有一个花费,表示经过该道路花费的时间。

Mr. Panda 喜欢在他的N个花园中转悠,然后采尽可能多的同种颜色的花。然而,有时候他并不想花太多时间走同一段路。现在问题来了,每一次 Mr. Panda 会告诉你:他从哪个花园开始出发和他能忍受的走同一段路的花费的最大值w(也就是说,只有费用不超过w的道路可以通行)。

请你判断Mr. Panda最多能采到的花是哪种颜色的花。如果有多种颜色符合条件,选择颜色编号最小的输出。

Input

第一行包含三个整数 N,M,type ,分别表示花园数目、道路数目和数据是否加密。

接下来一行N个整数,第i个整数表示第i个花园中的花的颜色

接下来M行表示花园中的道路,每行三个整数 x,y,w ,表示有一条花费为w的道路连接x号花园和y号花园。

接下来一个整数Q,表示Q组询问。

接下来Q行,每行一组询问x, w,表示Mr. Panda从x号花园出发,他能忍受的走同一段路的花费的最大值w。如果type=0,则输入给定的x和w均为真实的x和w。如果type=1,则输入给定的x和w均为加密后的x和w。设上一次询问的答案为last,则需要将x和w均与last异或后才能得到真实的x和w。特别地,对于第一组询问,last = 0。

Output

       输出Q行,每行一个整数表示Mr. Panda最多能采到的花是哪种颜色的花。如果有多种颜色符合条件,选择颜色编号最小的输出。

Sample Input

【样例输入1】
5 6 0
2 1 1 3 2
1 2 2
1 3 4
2 3 7
3 4 5
4 5 6
5 3 3
4
1 1
2 2
4 4
5 8
【样例输入2】
5 6 1
2 1 1 3 2
1 2 2
1 3 4
2 3 7
3 4 5
4 5 6
5 3 3
4
1 1
0 0
5 5
6 11

Sample Output

【样例输出1】
2
1
3
1
【样例输出2】
2
1
3
1

HINT

【样例解释】

第二组数据解密后即是第一组数据。

第一组询问:没有路可以走,故从1号点只能采颜色2的花1朵,故答案为2。

第二组询问:第1条路可以走,故从2号点开始可以采颜色1的花1朵,颜色2的花1朵,故答案为1。

第三组询问:第1、2、6条路可以走,故从4号点开始可以采颜色3的花1朵,故答案为3。

第四组询问:所有路都可以走,故从5号点开始可以采颜色1的花2朵,颜色2的花2朵,颜色3的花1朵,故答案为1。

【数据范围与约定】

本题设有5个测试点。

第1个测试点: N≤2×103,M,Q≤4×103,type=1

第2个测试点: N≤5×104,M,Q≤1×105,type=0

第3个测试点: N≤1×105,M,Q≤2×105,type=0

第4个测试点: N≤5×104,M,Q≤1×105,type=1

第5个测试点: N≤1×105,M,Q≤2×105,type=1

对于所有数据:

1≤N≤105

1≤M,Q≤2×105

1≤x,y,ci≤N

1≤w≤106

解法:可持久化并查集、可持久化线段树。

考虑Kruscal的过程,合并两个节点时,新建一个节点后把原来的节点视为新节点的左右儿子。

这样可以建出一个树,每次询问相当于询问这棵树上一个子树颜色的众数。线段树合并(启发式合并)即可。

代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<map>
using namespace std;
const int Maxn=1e6+50;
const int Maxm=5e6+50;
const int INF=0x3f3f3f3f;
inline int read()
{char ch=getchar();int i=0,f=1;while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){i=(i<<3)+(i<<1)+ch-'0';ch=getchar();}return i*f;
}
struct tr
{int lc,rc;pair<int,int >mx;
}tr[Maxm];
int n,m,type,cnt,last,num[Maxn];
int father[Maxn],fw[Maxn],sze[Maxm],rt[Maxn];
struct node
{int x,y,w;friend inline bool operator <(const node &a,const node &b){return a.w<b.w;}
}edge[Maxn];
map<int,int>to[Maxn];
inline int getf(int x,int w=INF)
{if(father[x]==x||w<fw[x])return x;return getf(father[x],w);
}
inline int Merge(int l,int r,int x1,int x2)
{if(!x1)return x2;if(!x2)return x1;int x=++cnt;if(l==r)tr[x].mx=make_pair(tr[x1].mx.first+tr[x2].mx.first,tr[x1].mx.second);else{int mid=(l+r)>>1;tr[x].lc=Merge(l,mid,tr[x1].lc,tr[x2].lc);tr[x].rc=Merge(mid+1,r,tr[x1].rc,tr[x2].rc);tr[x].mx=max(tr[tr[x].lc].mx,tr[tr[x].rc].mx);}return x;
}
inline int Build(int l,int r,int val)
{int x=++cnt;tr[x].mx=make_pair(1,-val);if(l!=r){int mid=(l+r)>>1;if(val<=mid)tr[x].lc=Build(l,mid,val);else tr[x].rc=Build(mid+1,r,val);}return x;
}
inline int Query(int x,int w)
{int f=getf(x,w);auto it=to[f].upper_bound(w);it--;return -tr[it->second].mx.second;
}
int main()
{//freopen("lx.in","r",stdin);n=read(),m=read(),type=read();for(int i=1;i<=n;i++){num[i]=read();father[i]=i;fw[i]=0;sze[i]=1;to[i][0]=rt[i]=Build(1,n,num[i]);}for(int i=1;i<=m;i++){edge[i].x=read(),edge[i].y=read(),edge[i].w=read();}sort(edge+1,edge+m+1);for(int i=1;i<=m;i++){int x=edge[i].x,y=edge[i].y,w=edge[i].w;x=getf(x),y=getf(y);if(x!=y){if(sze[x]<sze[y])swap(x,y);father[y]=x;sze[x]+=sze[y];fw[y]=w;to[x][w]=rt[x]=Merge(1,n,rt[x],rt[y]);}}m=read();while(m--){int x=read(),w=read();if(type)x^=last,w^=last;printf("%d\n",last=Query(x,w));}
}


BJ模拟 Pandaria(可持续化并查集)相关推荐

  1. NOI模拟 : Vain (并查集维护割点)

    题意: 对于 1 ≤ i ≤ n, 求出点 i 度数强制为 1 的情况下最小生成树的最大边的权值. 题解: 相当于求出删掉每个点之后的MSTMSTMST的最大值. 我们按边的权值从小到大加入新图, 很 ...

  2. Gym - 101194G Pandaria (并查集+倍增+线段树合并)

    题意: 给定一个无向图.每个点有一种颜色.现在给定q个询问,每次询问x和w,求所有能通过边权值不超过w的边走到x的点的集合中,哪一种颜色的点出现的次数最多.次数相同时输出编号最小的那个颜色.强制在线. ...

  3. [kuangbin带你飞]专题五 并查集 题解+总结

    kuangbin带你飞:点击进入新世界 总结: 本人算是初学者中的初学者,欢迎交流~ 并查集的接触过的不多,大概只有普通并查集,带权并查集,种族并查集,传说中的可持续化并查集只是听说过还没有接触,不过 ...

  4. 并查集 ---- 扩展域并查集判二分图 + 循环模拟字典树 The 2020 ICPC Asia Macau Regional Contest C. Club Assignment (详解)

    题目链接 题目大意: 有n个数,现在要把他们拆分成两个集合,假设S为集合,有如下定义: f(S)={min(x⊕y)∣x,y∈S,andx!=y}f(S)=\{min(x\oplus y)|x,y\i ...

  5. HDU-3974 Assign the task 线段树 或 直接模拟多叉树 或 并查集 (三种方法)

    题目大意 t 组数据(t<=10),每组第一行一个 n 表示 n 个员工(n<=5e4),接下来 n-1 行,每行两个整数 u,v 表示 v 是 u 的上司 然后一行 m 表示有 m 个操 ...

  6. 并查集是什么?怎么模拟实现?如何应用?

    目录 一.什么是并查集? 二.并查集可以解决哪些问题? 三.并查集的模拟实现 3.1.并查集的定义 3.2.查询两个元素是否是同一个集合 3.3.合并两个集合 3.4.求集合个数 3.5.并查集完整代 ...

  7. Day10 堆排序、模拟堆 trie树(字典树) 并查集

    堆呢就是一棵树完全二叉树... 小根堆的话,根节点就是最小值 维护堆只有两个操作 up(k) down(k) cnt是堆的大小 建堆的话只需要把前n/2的数down下来就ok 复杂度是小于O(n) 的 ...

  8. zcmu 1603 卡斯丁狗的战舰帝国(并查集+模拟)

    思路:看到题目我只知道,普通的暴力模拟是不行的,但是不知道用什么办法优化,然后看到网上的大佬们用了并查集恍然大悟: 用并查集维护每条船攻击后的根节点,最后输出查询位置的根节点就行,如果在期间存在该位置 ...

  9. 【洛谷P4997】不围棋【并查集】【模拟】

    题目大意: 题目链接:https://www.luogu.org/problemnew/show/P4997 「不围棋」是一种非常有趣的棋类游戏. 大家都知道,围棋的「气」是指一个棋子所在的联通块相邻 ...

最新文章

  1. 【管理心得之一】不要用“可有可无”的事,挑战他人对这件事的原则和底线...
  2. 【PC工具】传说中最好的编程手册管理软件Zeal,支持194种编程文档,学习编程语法查阅必备工具...
  3. spring boot 框架搭建
  4. nn.LayerNorm的参数
  5. 可调稳压电源lm317实验报告_LM317可调直流稳压电源DIY,非常实用!
  6. log算子 和dog 算子
  7. 未能成功加载扩展程序_JVM类加载 - 大碗炸酱面
  8. 【转载】白素贞的身世之谜
  9. python求两个向量的夹角
  10. nar神经网络_基于神经网络的预测模型
  11. sin_cos_tan_cot_sec_cosec 三角函数计算器
  12. JBoss、Geronimo及Tomcat比较分析
  13. 云服务器怎么连,云主机连接操作步骤是怎样的?
  14. 产品冷思考:大而全or小而美如何选择?
  15. 爱情没有了,生活仍在继续
  16. 微信小程序源码案例大全
  17. 为什么特斯拉Q2业绩能超预期?
  18. 新的放假规定,大年三十还得朝九晚五!
  19. #五、江恩的共振点是什么?
  20. 栅格地图建立-Grid-Mapping

热门文章

  1. spring boot在线投票系统 毕业设计源码141307
  2. nova7计算机复制后为啥会就在桌面,华为nova7怎么调返回键
  3. UIButton 加载网络图片
  4. Macbook电脑风扇温控Macs Fan Control Pro
  5. ABAP BDC 实例
  6. 艾永亮:企业如何用超级产品方法论突破瓶颈期?
  7. 房市静心贴:蛋蛋读NVMe之三
  8. adj_voc.pkl
  9. 企业及个人如何有效防护网络攻击
  10. 电脑删除文件提示错误:0x80070091目录不是空的 无法删除的解决办法