link

题意:

给一张n个点m条边的无向图,有q个询问,每次询问给出s,t,l,r,问你能否从s走到t,并且初始为人形,结束时必须为狼形,你是人形的时候必须避开$[1,l)$的节点,狼形的时候必须避开$(r,n]$的节点,你只能在$[L,R]$的节点处变身?

$n,q\leq  2\times 10^5,m\leq 4\times 10^5.$

题解:

get技能——Kruskal重构树

重构树是一个类似堆的结构,节点u比它的所有儿子v的权都要来的小/大(在这题中都有用到),可以用并查集建树。

考虑题中s~t有合法路径相当于,s只经过L~N的点能到达的点集和t只经过1~R的点能到达的点集有交。

那么考虑建出Kruskal最大/小重构树,那么两个点集分别对应到两棵树上的一个子树,求出dfs序转化成两个区间。

把每个点对应到一个坐标$[dfn1,dfn2]$(在两棵树中dfs序上的位置),原问题等价于询问一个矩形$x∈[l1,r1],y∈[l2,r2]$中是否有点,离线树状数组即可。

复杂度$\mathcal{O}(n\log n)$。

code:

 #include<bits/stdc++.h>
#include "werewolf.h"
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
#define per(i,x,y) for (int i=(x);i>=(y);i--)
#define ll long long
#define VI vector<int>
using namespace std;
const int N=2e5+;
int u,v,n,m,Q,top,bit[N]; VI ans,G[N];
struct node{
int x,y,ty,op,id;
node(){}
node(int x,int y,int ty,int op,int id):x(x),y(y),ty(ty),op(op),id(id){}
}q[N*];
bool cmp(node x,node y){ return x.x<y.x||x.x==y.x&&x.ty<y.ty; }
struct Kruskal_rebuild_tree{
int cnt,head[N],fa[N],clk,in[N],out[N],f[N][];
struct edge{ int to,nxt; }e[N];
void adde(int x,int y){ e[++cnt].to=y; e[cnt].nxt=head[x]; head[x]=cnt; }
int getfa(int x){ return x==fa[x]?x:fa[x]=getfa(fa[x]); }
void dfs(int u,int ty){
rep (i,,) f[u][i]=f[f[u][i-]][i-];
in[u]=++clk;
for (int i=head[u];i;i=e[i].nxt) f[e[i].to][]=u,dfs(e[i].to,ty);
out[u]=clk;
}
void build(int ty){
cnt=; rep (x,,n) fa[x]=x,head[x]=;
if (!ty){
per (x,n,)
for (auto y:G[x])
if (x<y&&getfa(x)!=(y=getfa(y))) adde(x,y),fa[y]=x;
} else{
rep (x,,n)
for (auto y:G[x])
if (x>y&&getfa(x)!=(y=getfa(y))) adde(x,y),fa[y]=x;
}
rep (i,,n) if (getfa(i)==i) dfs(i,ty);
}
int qry(int x,int lim,int ty){
per (i,,)
if (f[x][i]&&(!ty?f[x][i]>=lim:f[x][i]<=lim)) x=f[x][i];
return x;
}
}T[];
void add(int x){ for (;x<=n;x+=x&-x) bit[x]++; }
int qry(int x){ int s=; for (;x;x-=x&-x) s+=bit[x]; return s; }
VI check_validity(int _n,VI x,VI y,VI s,VI t,VI l,VI r){
n=_n; m=x.size(),Q=s.size();
rep (i,,m-) G[++x[i]].push_back(++y[i]),G[y[i]].push_back(x[i]);
T[].build(); T[].build();
rep (i,,n) q[++top]=node(T[].in[i],T[].in[i],,,);
rep (i,,Q-){
++s[i],++t[i],++l[i],++r[i];
int u=T[].qry(s[i],l[i],),v=T[].qry(t[i],r[i],);
int l1=T[].in[u],r1=T[].out[u],l2=T[].in[v],r2=T[].out[v];
q[++top]=node(r1,r2,,,i);
if (l1>) q[++top]=node(l1-,r2,,-,i);
if (l2>) q[++top]=node(r1,l2-,,-,i);
if (l1>&&l2>) q[++top]=node(l1-,l2-,,,i);
}
sort(q+,q++top,cmp); ans.resize(Q);
rep (i,,top)
if (!q[i].ty) add(q[i].y); else ans[q[i].id]+=qry(q[i].y)*q[i].op;
rep (i,,Q-) ans[i]=!!ans[i];
return ans;
}

uoj407 【IOI2018】狼人的更多相关文章

  1. [IOI2018]狼人

    [IOI2018]狼人 luogu UOJ 对人形和狼形分别建克鲁斯卡尔重构树 每次询问就是对于两棵树dfs序的一个二维数点,主席树维护 #include<bits/stdc++.h> u ...

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

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

  3. [IOI2018]狼人——kruskal重构树+可持久化线段树

    题目链接: IOI2018werewolf 题目大意:给出一张$n$个点$m$条边的无向图,点和边可重复经过,一个狼人初始为人形,有$q$次询问,每次询问要求人形态只能处于编号不小于$L$的点,狼形态 ...

  4. Luogu4899 IOI2018狼人(kruskal重构树+主席树)

    可以发现询问的即是“由起点开始‘只经过编号大于等于l的点’所形成的连通块”与“由终点开始‘只经过编号小于等于r的点’所形成的连通块”是否有交集.于是建出重构树,就可以知道每个询问的连通情况了.现在要知 ...

  5. ghj1222被坑记录[不持续更新]

    考试注意事项:link1 link2 (密码:wangle) 调不出来bug,可以先透彻一会儿或者是上个厕所或者坐一会别的题(间隔至少20min),然后通读代码 -1. 考试先读题,读题之后搞出一个做 ...

  6. [note]克鲁斯卡尔重构树

    克鲁斯卡尔重构树 又叫并查集重构树 大概在NOI2018之前还是黑科技 现在?烂大街了 主要是针对图上的对边有限制的一类问题 比如每次询问一个点u不能经过边权大于w的边能走到的第k大点权是多少 也就是 ...

  7. NOIWC2019游记

    更新完了? ghj1222这个智障因为NOIP考的太菜没有去THUWC和PKUWC,但是NOIWC还是苟进去了 由于已经结束了,好多事实忘了,所以可能不完整 2019/1/23 Wednesday 明 ...

  8. [IOI2018] werewolf 狼人

    [IOI2018] werewolf 狼人 IOI2018题解 (其实原题强制在线,要用主席树) 代码: 注意: 1.下标从0~n-1 2.kruskal重构树开始有n个节点,tot从n开始,++to ...

  9. [IOI2018] werewolf 狼人 kruskal重构树,主席树

    [IOI2018] werewolf 狼人 LG传送门 kruskal重构树好题. 日常安利博客文章 这题需要搞两棵重构树出来,这两棵重构树和我们平时见过的重构树有点不同(据说叫做点权重构树?),根据 ...

随机推荐

  1. 20165230 2017-2018-2 《Java程序设计》第8周学习总结

    20165230 2017-2018-2 <Java程序设计>第8周学习总结 教材学习内容总结 第十二章 java多线程机制 一个进程在其执行过程中,可产生多个线程.线程是比进程更小的执行 ...

  2. SolrJ API 官方文档最佳实践

    以下内容译自Solr Wiki官方文档,版权没有,随意转载. Solrj 是一个访问solr的Java客户端.它提供了一个java接口用于添加更新和查询solr索引.本页面介绍SolrJ最新版本1.4 ...

  3. Linux输入子系统:多点触控协议 -- multi-touch-protocol.txt【转】

    转自:http://blog.csdn.net/droidphone/article/details/8434768 Multi-touch (MT) Protocol --------------- ...

  4. MySQL分布式集群之MyCAT(二)【转】

    在第一部分,有简单的介绍MyCAT的搭建和配置文件的基本情况,这一篇详细介绍schema的一些具体参数,以及实际作用        首先贴上自己测试用的schema文件,双引号之前的反斜杠不会消除,姑 ...

  5. 手动实现图片预览-放大缩小全屏支持IE9以上

    #{extends '/Index/index.html' /} #{set title:'意见反馈' /} <script src="/public/mgr/javascripts/ ...

  6. Python类相关的装饰器

    一.装饰器装饰类方法 from functools import wraps def wrapper(func): @wraps(func) def inner(self,*args,**kwargs ...

  7. 03 Editor plugins and IDEs 编辑器插件和 ide

    Editor plugins and IDEs  编辑器插件和 ide Introduction  介绍 Options 选项   Introduction 介绍 This document list ...

  8. mysql命令gruop by报错this is incompatible with sql_mode=only_full_group_by

    在mysql 工具 搜索或者插入数据时报下面错误: ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause ...

  9. python面向对象(七)属性方法的添加

    ​ 通常情况下,当我们定义了一个class,创建了一个class的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性.下来我就讲下添加属性和方法,同时也将下限值添加属性方法. 添加属性 ...

  10. Focal Loss for Dense Object Detection 论文阅读

    何凯明大佬 ICCV 2017 best student paper 作者提出focal loss的出发点也是希望one-stage detector可以达到two-stage detector的准确 ...