快咕一个月了

咕咕咕 咕咕咕咕

LOJ #2865 Luogu P4899(离线)

UOJ #407(强制在线)


题意

给定一棵树和若干组询问$(S,E,L,R)$

表示你初始在$S$,想到达$E$,有一次变身机会,变身前经过的点的编号不得小于$L$,变身后不得大于$R$

判断每组询问是否可行

数据范围差不多都是$2·10^5$


题解

原问题等价于【从$ S$点出发不经过编号小于$ L$的点能到达的点集】和【从$ E$点出发不经过编号大于$ R$的点能到达的点集】是否有交

维护一棵最大克鲁斯卡尔重构树和一棵最小克鲁斯卡尔重构树

现在相当于每次询问两棵树上各一棵子树中是否编号集合有交

转化成二维数点问题

即每个点$ i$的坐标都是$(dfn_1[i],dfn_2[i])$

每次询问一个矩形中有没有点

离线可以树状数组扫描线水过

在线的话强上主席树即可

时间复杂度$ O(Q ·\log n)$


代码

这份是离线的

#include<ctime>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#define M 800010
#define rt register int
#define ll long long
using namespace std;
inline ll read(){
ll x=;char zf=;char ch=getchar();
while(ch!='-'&&!isdigit(ch))ch=getchar();
if(ch=='-')zf=-,ch=getchar();
while(isdigit(ch))x=x*+ch-'',ch=getchar();return x*zf;
}
void write(ll y){if(y<)putchar('-'),y=-y;if(y>)write(y/);putchar(y%+);}
void writeln(const ll y){write(y);putchar('\n');}
int k,m,n,x,y,z,ans,q;
struct ed{
int x,y;
}e[M];
bool cmp1(ed x,ed y){
return max(x.x,x.y)<max(y.x,y.y);
}
bool cmp2(ed x,ed y){
return min(x.x,x.y)>min(y.x,y.y);
}
struct tree{
int cnt,qwq;
int F[M],L[M],N[M],a[M],fa[M],ff[M],val[M],dfn[M],id[M],size[M],up[M][];
int ask(int x){return (x==fa[x])?x:(fa[x]=ask(fa[x]));}
void add(int x,int y){
a[++k]=y;
if(!F[x])F[x]=k;
else N[L[x]]=k;
L[x]=k;
}
int nomore(int x,int v){//包含x的经过边权不超过val的重构树上的点标号
for(rt i=;i>=;i--)if(val[up[x][i]]<=v&&up[x][i])x=up[x][i];
return x;
}
int noless(int x,int v){//包含x的经过边权不少于val的重构树上的点标号
for(rt i=;i>=;i--)if(val[up[x][i]]>=v&&up[x][i])x=up[x][i];
return x;
}
void init(){
for(rt i=;i<=cnt;i++)up[i][]=ff[i]; for(rt i=;i<=;i++)
for(rt j=;j<=cnt;j++)up[j][i]=up[up[j][i-]][i-];
}
void dfs(int x){
dfn[x]=++qwq;id[qwq]=x;size[x]=;
for(rt i=F[x];i;i=N[i]){
dfs(a[i]);
size[x]+=size[a[i]];
}
}
}S1,S2;//<=x和>=x
struct query{
int opt,pl,L,R,id;//opt:0点1,-1差分
bool operator <(const query s)const{
if(pl==s.pl)return (bool)opt<(bool)s.opt;
return pl<s.pl;
}
}a[M];
int anss[M],c[M];
void up(int x){
for(rt i=x;i<=n*;i+=i&-i)c[i]++;
}
int query(int x){
int ret=;
for(rt i=x;i;i&=i-)ret+=c[i];
return ret;
}
int main(){
n=read();m=read();q=read();
for(rt i=;i<m;i++){
x=read()+;y=read()+;
e[i]={x,y};
}
for(rt i=;i<=*n+;i++)S1.fa[i]=S2.fa[i]=S1.ff[i]=S2.ff[i]=i;
S1.cnt=S2.cnt=n;
sort(e,e+m,cmp1);
for(rt i=;i<m;i++){
int ls=S1.ask(e[i].x),rs=S1.ask(e[i].y);if(ls==rs)continue;
S1.cnt++;S1.fa[S1.cnt]=S1.cnt;
S1.fa[ls]=S1.fa[rs]=S1.ff[ls]=S1.ff[rs]=S1.cnt;S1.val[S1.cnt]=max(e[i].x,e[i].y);
S1.add(S1.cnt,ls);S1.add(S1.cnt,rs);
}
sort(e,e+m,cmp2);
for(rt i=;i<m;i++){
int ls=S2.ask(e[i].x),rs=S2.ask(e[i].y);if(ls==rs)continue;
S2.cnt++;S2.fa[S2.cnt]=S2.cnt;
S2.fa[ls]=S2.fa[rs]=S2.ff[ls]=S2.ff[rs]=S2.cnt;S2.val[S2.cnt]=min(e[i].x,e[i].y);
S2.add(S2.cnt,ls);S2.add(S2.cnt,rs);
}
S1.dfs(S1.cnt);S2.dfs(S2.cnt);S1.init();S2.init();
int t=;
for(rt i=;i<=n;i++)a[++t]={,S1.dfn[i],S2.dfn[i],,};
for(rt i=;i<q;i++){
int S=read()+,E=read()+,L=read()+,R=read()+;
int d2=S2.noless(S,L),d1=S1.nomore(E,R);
a[++t]={-,S1.dfn[d1]-,S2.dfn[d2],S2.dfn[d2]+S2.size[d2]-,i};
a[++t]={,S1.dfn[d1]+S1.size[d1]-,S2.dfn[d2],S2.dfn[d2]+S2.size[d2]-,i};
}
sort(a+,a+t+);
for(rt i=;i<=t;i++){
if(a[i].opt==)up(a[i].L);
else anss[a[i].id]+=a[i].opt*(query(a[i].R)-query(a[i].L-));
}
for(rt i=;i<q;i++)writeln((bool)anss[i]);
return ;
}

「IOI2018」狼人的更多相关文章

  1. @loj - 2865@ 「IOI2018」狼人

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 在日本的茨城县内共有 N 个城市和 M 条道路.这些城市是根据人 ...

  2. 【刷题】LOJ 2863 「IOI2018」组合动作

    题目描述 你在玩一个动作游戏.游戏控制器有 \(4\) 个按键,A.B.X 和 Y.在游戏中,你用组合动作来赚金币.你可以依次按这些按键来完成一个组合动作. 这个游戏有一个隐藏的按键序列,可以表示为由 ...

  3. [LOJ2865] P4899 [IOI2018] werewolf 狼人

    P4899 [IOI2018] werewolf 狼人 LOJ#2865.「IOI2018」狼人,第一次AC交互题 kruskal 重构树+主席树 其实知道重构树的算法的话,难度就主要在主席树上 习惯 ...

  4. 「译」JUnit 5 系列:条件测试

    原文地址:http://blog.codefx.org/libraries/junit-5-conditions/ 原文日期:08, May, 2016 译文首发:Linesh 的博客:「译」JUni ...

  5. 「译」JUnit 5 系列:扩展模型(Extension Model)

    原文地址:http://blog.codefx.org/design/architecture/junit-5-extension-model/ 原文日期:11, Apr, 2016 译文首发:Lin ...

  6. JavaScript OOP 之「创建对象」

    工厂模式 工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程.工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题. function createPers ...

  7. 「C++」理解智能指针

    维基百科上面对于「智能指针」是这样描述的: 智能指针(英语:Smart pointer)是一种抽象的数据类型.在程序设计中,它通常是经由类型模板(class template)来实做,借由模板(tem ...

  8. 「JavaScript」四种跨域方式详解

    超详细并且带 Demo 的 JavaScript 跨域指南来了! 本文基于你了解 JavaScript 的同源策略,并且了解使用跨域跨域的理由. 1. JSONP 首先要介绍的跨域方法必然是 JSON ...

  9. 「2014-5-31」Z-Stack - Modification of Zigbee Device Object for better network access management

    写一份赏心悦目的工程文档,是很困难的事情.若想写得完善,不仅得用对工具(use the right tools),注重文笔,还得投入大把时间,真心是一件难度颇高的事情.但,若是真写好了,也是善莫大焉: ...

随机推荐

  1. vue源码分析—Vue.js 源码构建

    Vue.js 源码是基于 Rollup 构建的,它的构建相关配置都在 scripts 目录下.(Rollup 中文网和英文网) 构建脚本 通常一个基于 NPM 托管的项目都会有一个 package.j ...

  2. df、du命令

     EXT3  最多只能支持32TB的文件系统和2TB的文件,实际只能容纳2TB的文件系统和16GB的文件 Ext3目前只支持32000个子目录 Ext3文件系统使用32位空间记录块数量和i-节点数量 ...

  3. 【深色模式】macOS Mojave+Visual Studio for Mac+FineUICore多图赏析!

    全面开启深色模式,今早成功升级到 macOS Mojave,下面就来欣赏一下吧. 点击图片,查看大图 1. 下载 macOS Mojave 2. 安装成功,开启深色模式 3. 来一张桌面截图 4. 开 ...

  4. 原创|1分钟搞定 Nginx 版本的平滑升级与回滚

    Nginx无论是对于运维.开发.还是测试来说,都是日常工作需要掌握的一个知识点,之前也写过不少关于Nginx相关的文章: Nginx服务介绍与安装 Nginx服务配置文件介绍 Nginx配置虚拟主机 ...

  5. 说说我心中的Linux系统

    我不知道在阅读此篇文章的你,是一个什么样的人,或许你只是偶然看到此篇文章的路人,或许是对linux有兴趣但没接触过linux的圈外人,或许是已经入行没多久的菜鸟,或许是喜欢linux却学习不下去预备放 ...

  6. java基础-jdk工具包

    1. 标准工具 这些工具都是JDK提供的,通常都是长期支持的工具,JDK承诺这些工具比较好用.不同系统.不同版本之间可能会有差异,但是不会突然就有一个工具消失. 1.1 基础包 (extcheck, ...

  7. JMC监控(Windows上远程连接监控Linux服务器的JVM)

    Windows上远程连接监控Linux服务器的JVM:1.Linux服务器上配置:在Tomcat的tomcat-wms/bin/catalina.sh中添加CATALINA_OPTS="-X ...

  8. spring整合junit进行测试

    以下只是一个模板,大家记得改变配置文件 package cn.itcast.crm.dao; import org.junit.Test; import org.junit.runner.RunWit ...

  9. 深入理解 GIL:如何写出高性能及线程安全的 Python 代码

    深入理解 GIL:如何写出高性能及线程安全的 Python 代码 本文由 伯乐在线 - 郑芸 翻译.未经许可,禁止转载!英文出处:A. Jesse.欢迎加入翻译组. GIL对多线程的影响:http:/ ...

  10. 「FHQ Treap」学习笔记

    话说天下大事,就像fhq treap —— 分久必合,合久必分 简单讲一讲.非旋treap主要依靠分裂和合并来实现操作.(递归,不维护fa不维护cnt) 合并的前提是两棵树的权值满足一边的最大的比另一 ...