题意 是 有n个花园 一个花园内所有的花的颜色都是一样的 有很多种不同的颜色  花园到花园之间有路,走不同的路有不同的代价
   如果选一个点作为起点 只走小于等于w的路  可以经过的这些花园里  那种颜色最多  多组询问 强制在线
   
解法   对于这个影响这个答案有两个因素 不可以把所有答案求出  一个一个求的话复杂度太高  因为强制在线所以我们需要先预处理一部分数据 然后根据预处理的数据 再进行求解 答案, 对于这个题面 很明显可以想到 先把边权最小的连起来 然后是次最大 然后再大点  依次
明显就是一个 求最小生成树的过程  每次链接一条边的时候 我们都可以 从当前局面 计算出一个答案 明确可以知道 存在一组询问的答案都是这个  用并差集维护 集合   当我们把两个集合 连接起来的时候 就把这两个 集合 链接到一个 点上  用这个点来代码 这个两个集合合并后的状态 一共有n个点 所以我们需要建立n-1个点   按照最小生成树建树的顺序 可以获得一个二叉树  对于这个二叉树 每一个节点都可以求一个答案  这些答案 可以回答所有询问,   这些节点一共是 2n-1个(前n个几乎不用考虑 就是本身)  我们只需要先把这n-1个结点的答案预处理出来就可以了  对于之后的询问 我们就可以使用 倍增 直接找到 从x点最高可以到的位置 从而得出答案   
对于那n-1的节点的答案维护 要使用线段树合并(合并树 最初的线段树要使用动态开点线段树 动态开点的话也就是一共树就是一条链 log2e5 不会超过20个  n个线段树的话直接开个n*20的内存就可以了)

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 2e5+7;
int color[maxn],f[maxn];
int find(int x){return f[x]==x?x:f[x]=find(f[x]);}
void init(int N){for(int i=1;i<=N;i++)f[i]=i;}
struct edge{int x,y,l;}E[maxn];
bool com(edge a,edge b){return a.l<b.l;}
struct Node{int l,r,mx;}node[maxn*20];
int N,M,tot,root[maxn];
void pushup(int rt){node[rt].mx=max(node[node[rt].l].mx,node[node[rt].r].mx);}
void bulit(int l,int r,int &rt,int pos)
{node[++tot]=(Node){0,0,0};rt=tot;if(l==r){node[rt].mx=1;return;}int m=(l+r)>>1;if(pos<=m)bulit(l,m,node[rt].l,pos);else bulit(m+1,r,node[rt].r,pos);pushup(rt);
}
void merge(int l,int r,int&x,int y)
{if(!x||!y){ x= x+y;return ;}if(l==r)node[x].mx+=node[y].mx;else{int m=(l+r)>>1;merge(l,m,node[x].l,node[y].l);merge(m+1,r,node[x].r,node[y].r);pushup(x);}
}
int ans[maxn],limt[maxn];
int getans(int l,int r,int x){if(l==r)return l;int m=(l+r)>>1;if(node[x].mx==node[node[x].l].mx)return getans(l,m,node[x].l);return getans(m+1,r,node[x].r);
}
int p[maxn][20];
int main()
{int T,cases=0,Q;scanf("%d",&T);while(T--){memset(p,0,sizeof(p));scanf("%d%d",&N,&M);for(int i=1;i<=N;i++)scanf("%d",color+i);for(int i=0;i<M;i++)scanf("%d%d%d",&E[i].x,&E[i].y,&E[i].l);sort(E,E+M,com);init(N*2+1);tot=0;int cnt=N;for(int i=1;i<=N;i++)bulit(1,N,root[i],color[i]),ans[i]=color[i];for(int i=0;i<M;i++){int x=find(E[i].x),y=find(E[i].y);if(x==y)continue;merge(1,N,root[x],root[y]);root[++cnt]=root[x];ans[cnt]=getans(1,N,root[x]);limt[cnt]=E[i].l;p[x][0]=p[y][0]=cnt;f[y]=f[x]=cnt;}for(int i=1;i<20;i++)for(int j=1;j<=cnt;j++)p[j][i]=p[p[j][i-1]][i-1];scanf("%d",&Q);printf("Case #%d:\n",++cases);int x,w,last=0;while(Q--){scanf("%d%d",&x,&w);x^=last;w^=last;for(int i=19;i>=0;i--)if(limt[p[x][i]]<=w&&p[x][i])x=p[x][i];printf("%d\n",last=ans[x]);}}return 0;
}

View Code

转载于:https://www.cnblogs.com/DWVictor/p/10283150.html

Pandaria(Kruskal重构树+线段树合并)相关推荐

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

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

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

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

  3. 【NOI模拟赛】最小生成树(kruskal算法,线段树合并)

    题面 (一道原创题,我直接扒图了 时限:2s,空间:1GB 题解 为了方便,下文认为 n , m , q n,m,q n,m,q 同阶.同样,不妨给每条边强制定大小,使得不存在两条边边权相等. 有一个 ...

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

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

  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 重构树 + 主席树)

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

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

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

  9. Problem G. Pandaria(线段树合并 + Kruskal 重构树)

    Problem G. Pandaria 给定一个有nnn条边的无向连通图,每条边有对应的边权,每个点有一个颜色, 问从一个点出发,经过不超过www的边权,所能到达的点中,颜色出现次数做多且颜色编号最小 ...

最新文章

  1. 在 Spring Boot 中,如何干掉 if else
  2. html5画布可以p图,HTML5图像适合发布在画布上
  3. IPC之哲学家进餐问题
  4. [转]使用fragments
  5. 结对项目 刘静 201303014059 计科高职13-2
  6. 使用剪切板[3]: SetComponent、GetComponent
  7. android文件存储的有点,快速理解Android文件存储路径
  8. 三星note10 android q,【极光ROM】-【三星NOTE10/NOTE10+/5G N97XX-855】-【V5.0 Android-Q-TD1】...
  9. Python+企业微信 实现简易自动化运维
  10. php遵义旅游管理系统毕业设计源码091801
  11. Apache NiFi简介
  12. 当前电子计算机发展的局限性,当前高中信息技术教学现状及教学改革探究
  13. 弱智的页面无法访问的问题
  14. libjvm.so stripped
  15. ubuntu20.04安装librtmp库 并在QT5中引入librtmp库
  16. 云盘里资料被和谐了,怎么办?
  17. Mysql5.5命令行修改密码
  18. linux man 路径,Linux中.man文件用法【转】
  19. 云端(Cloud)多租户网络技术
  20. linux服务器挂qq,在Linux系统下安装QQ的一般方法

热门文章

  1. HDU 3790 最短路径问题 裸跑dijkstra
  2. LTE射频拉远单元数字中频方案(七)
  3. mysql shutdown 命令_Mysql 5.7.9 shutdown 语法实例详解
  4. Windows系统查看硬盘序列号
  5. android正在升级正在优化应用程序,Android正在启动,优化应用是怎么回事,最近每次开机都这样。...
  6. 【论文分享】ARCUS: Symbolic Root Cause Analysis of Exploits in Production Systems
  7. win32 socket通信
  8. Windows 进程和作业
  9. 做外挂的一些原理。自己拿去研究。
  10. 快包_分治法求解凸包问题