[IOI2018]狼人
[IOI2018]狼人
luogu
UOJ
对人形和狼形分别建克鲁斯卡尔重构树
每次询问就是对于两棵树dfs序的一个二维数点,主席树维护
#include<bits/stdc++.h>
using namespace std;
const int _=4e5+5;
int re(){
    int x=0,w=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*w;
}
int n,m,q,S,rt[_],s[_<<4],ls[_<<4],rs[_<<4];
struct Edge{int u,v,w;}E[_];
bool cmp1(Edge a,Edge b){return a.w>b.w;}
bool cmp2(Edge a,Edge b){return a.w<b.w;}
struct Kruskal_tree{
    int tot,cnt,ts;
    int fa[_],val[_],f[20][_],r[_],id[_],h[_],dfn[_];
    bool tag;
    struct edge{int to,next;}e[_];
    int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
    void link(int u,int v){e[++cnt]=(edge){v,h[u]};h[u]=cnt;}
    void dfs(int u){
        dfn[u]=++ts;id[ts]=u;
        for(int i=h[u];i;i=e[i].next)
            dfs(e[i].to);
        r[u]=ts;
    }
    void init(){
        tot=n;
        for(int i=1;i<=n<<1;i++)fa[i]=i;
        for(int i=1;i<=n;i++)val[i]=i;
        for(int i=1;i<=m;i++){//克鲁斯卡尔重构树
            int x=find(E[i].u),y=find(E[i].v);
            if(x==y)continue;
            val[++tot]=E[i].w;
            link(tot,x);link(tot,y);
            f[0][x]=f[0][y]=fa[x]=fa[y]=tot;
        }
        for(int i=1;i<=18;i++)//预处理倍增数组
            for(int j=1;j<=tot;j++)
                f[i][j]=f[i-1][f[i-1][j]];
        dfs(tot);//预处理dfs序
    }
    int work(int x,int k){//倍增
        for(int i=18;i>=0;i--)
            if(f[i][x]&&((val[f[i][x]]>=k&&tag)||(!tag&&val[f[i][x]]<=k)))
                x=f[i][x];
        return x;
    }
}man,wolf;
void upd(int&x,int l,int r,int k){
    s[++S]=s[x]+1;ls[S]=ls[x];rs[S]=rs[x];
    x=S;if(l==r)return;int mid=(l+r)>>1;
    if(k<=mid)upd(ls[x],l,mid,k);
    else upd(rs[x],mid+1,r,k);
}
int query(int x,int y,int l,int r,int ql,int qr){
    if(ql<=l&&r<=qr)return s[y]-s[x];
    int mid=(l+r)>>1,res=0;
    if(ql<=mid)res=query(ls[x],ls[y],l,mid,ql,qr);
    if(qr>mid)res+=query(rs[x],rs[y],mid+1,r,ql,qr);
    return res;
}
int main(){
    n=re(),m=re(),q=re();
    for(int i=1;i<=m;i++){
        E[i].u=re()+1,E[i].v=re()+1;
        E[i].w=min(E[i].u,E[i].v);
    }
    man.tag=1;
    sort(E+1,E+m+1,cmp1);
    man.init();
    for(int i=1;i<=m;i++)E[i].w=max(E[i].u,E[i].v);
    sort(E+1,E+m+1,cmp2);
    wolf.init();
    //预处理主席树
    for(int i=1;i<=man.tot;i++){
        rt[i]=rt[i-1];
        if(man.id[i]<=n)upd(rt[i],1,wolf.tot,wolf.dfn[man.id[i]]);
    }
    while(q--){
        int s=re()+1,t=re()+1,L=re()+1,R=re()+1;
        int A=man.work(s,L),B=wolf.work(t,R);
        if(query(rt[man.dfn[A]-1],rt[man.r[A]],1,wolf.tot,wolf.dfn[B],wolf.r[B]))puts("1");
        else puts("0");
    }
    return 0;
}
												
											[IOI2018]狼人的更多相关文章
- LOJ.2865.[IOI2018]狼人(Kruskal重构树 主席树)
		
LOJ 洛谷 这题不就是Peaks(加强版)或者归程么..这算是\(IOI2018\)撞上\(NOI2018\)的题了? \(Kruskal\)重构树(具体是所有点按从小到大/从大到小的顺序,依次加入 ...
 - [IOI2018]狼人——kruskal重构树+可持久化线段树
		
题目链接: IOI2018werewolf 题目大意:给出一张$n$个点$m$条边的无向图,点和边可重复经过,一个狼人初始为人形,有$q$次询问,每次询问要求人形态只能处于编号不小于$L$的点,狼形态 ...
 - Luogu4899 IOI2018狼人(kruskal重构树+主席树)
		
可以发现询问的即是“由起点开始‘只经过编号大于等于l的点’所形成的连通块”与“由终点开始‘只经过编号小于等于r的点’所形成的连通块”是否有交集.于是建出重构树,就可以知道每个询问的连通情况了.现在要知 ...
 - ghj1222被坑记录[不持续更新]
		
考试注意事项:link1 link2 (密码:wangle) 调不出来bug,可以先透彻一会儿或者是上个厕所或者坐一会别的题(间隔至少20min),然后通读代码 -1. 考试先读题,读题之后搞出一个做 ...
 - [note]克鲁斯卡尔重构树
		
克鲁斯卡尔重构树 又叫并查集重构树 大概在NOI2018之前还是黑科技 现在?烂大街了 主要是针对图上的对边有限制的一类问题 比如每次询问一个点u不能经过边权大于w的边能走到的第k大点权是多少 也就是 ...
 - NOIWC2019游记
		
更新完了? ghj1222这个智障因为NOIP考的太菜没有去THUWC和PKUWC,但是NOIWC还是苟进去了 由于已经结束了,好多事实忘了,所以可能不完整 2019/1/23 Wednesday 明 ...
 - [IOI2018] werewolf 狼人
		
[IOI2018] werewolf 狼人 IOI2018题解 (其实原题强制在线,要用主席树) 代码: 注意: 1.下标从0~n-1 2.kruskal重构树开始有n个节点,tot从n开始,++to ...
 - [IOI2018] werewolf 狼人 kruskal重构树,主席树
		
[IOI2018] werewolf 狼人 LG传送门 kruskal重构树好题. 日常安利博客文章 这题需要搞两棵重构树出来,这两棵重构树和我们平时见过的重构树有点不同(据说叫做点权重构树?),根据 ...
 - [LOJ2865] P4899 [IOI2018] werewolf 狼人
		
P4899 [IOI2018] werewolf 狼人 LOJ#2865.「IOI2018」狼人,第一次AC交互题 kruskal 重构树+主席树 其实知道重构树的算法的话,难度就主要在主席树上 习惯 ...
 
随机推荐
- asp.net+mvc+easyui+sqlite 简单用户系统学习之旅(二)—— easyui的简单实用
			
下面开始在UserManager.Web中利用easyUI构建web. 1. 先删除自带的controllers.models和views(里面的shared和web.config可以保存)下面的文件 ...
 - ASP.NET MVC传递Model到视图的多种方式总结
			
ASP.NET MVC传递Model到视图的多种方式总结 有多种方式可以将数据传递到视图,如下所示: ViewData ViewBag PartialView TempData ViewModel T ...
 - 通过windows自带的系统监视器来查看IIS并发连接数(perfmon.msc)
			
如果要查看IIS连接数,最简单方便的方法是通过“网站统计”来查看,“网站统计”的当前在线人数可以认为是当前IIS连接数.然而,“网站统计”的当前在线人数统计时间较长,一般为10分钟或15分钟,再加上统 ...
 - MTU的概念,什么是路径MTU? MTU发现机制,TraceRoute(了解)
			
1.MTU的概念 MTU即Maximum Transmission Unit 最大传输单元.它是指一种通信协议的某一层上面所能通过的最大数据包大小(以字节为单位). 2.路径MTU ...
 - Linux中如何配置IP
			
与网络相关的文件:1) /etc/sysconfig/network 设置主机名称及能否启动Network2) /etc/sysconfig/network-scripts/ifcfg-eth ...
 - PE下挂载注册表文件然后清除系统托盘空白图标缓存
			
清除了右下角通知栏图标缓存TrayNotify(否则会出现一堆空白图标)清除缓存批处理脚本.bat如何在PE系统环境下清除宿主系统的托盘图标缓存? 清除了右下角通知栏图标缓存TrayNotify(否则 ...
 - 每天进步一点点——Linux中的文件描写叙述符与打开文件之间的关系
			
转载请说明出处:http://blog.csdn.net/cywosp/article/details/38965239 1. 概述 在Linux系统中一切皆能够看成是文件,文件又可分为:普通 ...
 - sql语句单据编号生成防并发
			
有用户反馈说发现重复单据号,检查发现以下单据号被分配给了不同的两个职工 系统中使用语句exec GetNewOrderNumber 'pwgnumber','PWG',1, @pwg_number o ...
 - java继承机制
			
1 继承 关键字:extends java没有多重继承 实例 父类: package unit4; public class Base { public int publicVarofBase= ...
 - python 分支结构
			
if 语句 if语句 计算机之所以能做很多自动化的任务,因为它可以自己做条件判断. 比如,输入用户年龄,根据年龄打印不同的内容,在Python程序中,可以用if语句实现: age = 20 if ag ...