[IOI 2018] Werewolf
[题目链接]
https://www.luogu.org/problemnew/show/P4899
[算法]
建出原图的最小/最大生成树的kruskal重构树然后二维数点
时间复杂度 : O((N+Q)logN)
[代码]
#include<bits/stdc++.h>
using namespace std;
#define N 200010
#define M 400010
#define MAXLOG 20
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull; template <typename T> inline void chkmin(T &x , T y) { x = min(x , y); }
template <typename T> inline void chkmax(T &x , T y) { x = max(x , y); }
template <typename T> inline void read(T &x)
{
T f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
x *= f;
} struct info
{
int x , y;
} a[M];
struct edge
{
int to , nxt;
} ea[N << ] , eb[N << ]; int n , m , q , tot , timera , timerb , cnta , cntb;
int la[N << ] , ra[N << ] , fathera[N << ][MAXLOG] , fatherb[N << ][MAXLOG] ,
deptha[N << ] , depthb[N << ] , rt[N << ] , heada[N << ] , headb[N << ] ,
lb[N << ] , rb[N << ] , fa[N << ] , valuea[N << ] , valueb[N << ] , w[N << ]; struct Presitent_Segment_Tree
{
int sz;
Presitent_Segment_Tree()
{
sz = ;
}
struct node
{
int lc , rc;
int cnt;
} a[N * ];
inline void modify(int &now , int old , int l , int r , int x , int value)
{
now = ++sz;
a[now].lc = a[old].lc , a[now].rc = a[old].rc;
a[now].cnt = a[old].cnt + value;
if (l == r) return;
int mid = (l + r) >> ;
if (mid >= x) modify(a[now].lc , a[old].lc , l , mid , x , value);
else modify(a[now].rc , a[old].rc , mid + , r , x , value);
}
inline int query(int rt1 , int rt2 , int l , int r , int ql , int qr)
{
if (l == ql && r == qr)
return a[rt1].cnt - a[rt2].cnt;
int mid = (l + r) >> ;
if (mid >= qr) return query(a[rt1].lc , a[rt2].lc , l , mid , ql , qr);
else if (mid + <= ql) return query(a[rt1].rc , a[rt2].rc , mid + , r , ql , qr);
else return query(a[rt1].lc , a[rt2].lc , l , mid , ql , mid) + query(a[rt1].rc , a[rt2].rc , mid + , r , mid + , qr);
}
} PST;
inline void addedgea(int u , int v)
{
++tot;
ea[tot] = (edge){v , heada[u]};
heada[u] = tot;
}
inline void addedgeb(int u , int v)
{
++tot;
eb[tot] = (edge){v , headb[u]};
headb[u] = tot;
}
inline void dfsa(int u , int par)
{
fathera[u][] = par;
deptha[u] = deptha[par] + ;
for (int i = ; i < MAXLOG; i++)
fathera[u][i] = fathera[fathera[u][i - ]][i - ];
la[u] = ++timera;
for (int i = heada[u]; i; i = ea[i].nxt)
{
int v = ea[i].to;
if (v == par) continue;
dfsa(v , u);
}
ra[u] = timera;
}
inline void dfsb(int u , int par)
{
fatherb[u][] = par;
depthb[u] = depthb[par] + ;
for (int i = ; i < MAXLOG; i++)
fatherb[u][i] = fatherb[fatherb[u][i - ]][i - ];
lb[u] = ++timerb;
for (int i = headb[u]; i; i = eb[i].nxt)
{
int v = eb[i].to;
if (v == par) continue;
dfsb(v , u);
}
rb[u] = timerb;
}
inline bool cmpa(info a , info b)
{
return min(a.x , a.y) > min(b.x , b.y);
}
inline bool cmpb(info a , info b)
{
return max(a.x , a.y) < max(b.x , b.y);
}
inline int getroot(int x)
{
if (fa[x] == x) return x;
else return fa[x] = getroot(fa[x]);
}
inline void kruskalA()
{
int tot = ;
cnta = n;
timera = ;
sort(a + , a + m + , cmpa);
for (int i = ; i <= * n; i++) fa[i] = i;
for (int i = ; i <= m; i++)
{
int fu = getroot(a[i].x) , fv = getroot(a[i].y);
if (fu != fv)
{
++cnta;
addedgea(cnta , fu);
addedgea(cnta , fv);
valuea[cnta] = min(a[i].x , a[i].y);
fa[fu] = fa[fv] = fa[cnta] = cnta;
++tot;
}
if (tot == n - ) break;
}
dfsa(cnta , );
}
inline void kruskalB()
{
int tot = ;
cntb = n;
timerb = ;
sort(a + , a + m + , cmpb);
for (int i = ; i <= * n; i++) fa[i] = i;
for (int i = ; i <= m; i++)
{
int fu = getroot(a[i].x) , fv = getroot(a[i].y);
if (fu != fv)
{
++cntb;
addedgeb(cntb , fu);
addedgeb(cntb , fv);
valueb[cntb] = max(a[i].x , a[i].y);
fa[fu] = fa[fv] = fa[cntb] = cntb;
++tot;
}
if (tot == n - ) break;
}
dfsb(cntb , );
}
inline bool query(int l1 , int r1 , int l2 , int r2)
{
return PST.query(rt[r1] , rt[l1 - ] , , * n , l2 , r2);
} int main()
{ read(n); read(m); read(q);
for (int i = ; i <= m; i++)
{
read(a[i].x);
read(a[i].y);
++a[i].x; ++a[i].y;
}
kruskalA();
kruskalB();
for (int i = ; i <= n; i++) w[la[i]] = lb[i];
for (int i = ; i <= * n; i++) PST.modify(rt[i] , rt[i - ] , , * n , w[i] , );
for (int i = ; i <= q; i++)
{
int s , e , l , r;
read(s); read(e); read(l); read(r);
++s; ++e; ++l; ++r;
if (s < l || e > r)
{
puts("");
continue;
}
for (int i = MAXLOG - ; i >= ; i--)
if (fathera[s][i] && valuea[fathera[s][i]] >= l)
s = fathera[s][i];
for (int i = MAXLOG - ; i >= ; i--)
if (fatherb[e][i] && valueb[fatherb[e][i]] <= r)
e = fatherb[e][i];
if (query(la[s] , ra[s] , lb[e] , rb[e])) puts("");
else puts("");
} return ;
}
[IOI 2018] Werewolf的更多相关文章
- 【IOI 2018】Werewolf 狼人
虽然作为IOI的Day1T3,但其实不是一道很难的题,或者说这道题其实比较套路吧. 接下来讲解一下这个题的做法: 如果你做过NOI 2018的Day1T1,并且看懂了题面,那你很快就会联想到这道题,因 ...
- 【IOI 2018】Combo 组合动作(模拟,小技巧)
题目链接 IOI的签到题感觉比NOI的签到题要简单啊,至少NOI同步赛我没有签到成功…… 其实这个题还是挺妙妙的,如果能够从题目出发,利用好限制,应该是可以想到的做法的. 接下来开始讲解具体的做法: ...
- 【IOI 2018】Highway 高速公路收费
这是一道极好的图论题,虽然我一开始只会做$18$分,后来会做$51$分,看着题解想了好久才会做(吐槽官方题解:永远只有一句话),但这的确是一道好题,值得思考,也能启发思维. 如果要讲这道题,还是要从部 ...
- 【IOI 2018】Doll 机械娃娃
我感觉这个题作为Day2T1,有一定的挑战性.为$Rxd$没有完成这道题可惜. 我觉得这道题,如果按照前几个部分分的思路来想,就有可能绕进错误的思路中.因为比如说每个传感器最多只在序列中出现$2$次, ...
- Before NOIP 2018
目录 总结 刷题 2018 - 9 - 24 2018 - 9 - 25 2018 - 9 - 26 2018 - 9 - 27 2018 - 9 - 28 2018 - 9 - 29 2018 - ...
- HDU - 6370 Werewolf 2018 Multi-University Training Contest 6 (DFS找环)
求确定身份的人的个数. 只能确定狼的身份,因为只能找到谁说了谎.但一个人是否是民,无法确定. 将人视作点,指认关系视作边,有狼边和民边两种边. 确定狼的方法只有两种: 1. 在一个仅由一条狼边组成的环 ...
- [日常] PKUWC 2018爆零记
吃枣药丸...先开个坑... day -1 上午周测...大翻车... 下午被查水表说明天必须啥啥啥...(当时我差点笑出声) 晚上领到笔记本一枚和一袋耗材(袜子) 然而班会开太晚回去没来得及收拾就晚 ...
- OI生涯回忆录 2018.11.12~2019.4.15
上一篇:OI生涯回忆录 2017.9.10~2018.11.11 一次逆风而行的成功,是什么都无法代替的 ………… 历经艰难 我还在走着 一 NOIP之后,全机房开始了省选知识的自学. 动态DP,LC ...
- CTSC 2018 游记
day0 李总提前一天放假,回家颓整理行李... 然而我... 早上:睡觉... 中午:睡觉... 晚上:睡觉去火车站... 吃了几把鸡,本来想带李总入坑,但他挥手拒绝然后被李总带进了炸金花的坑... ...
随机推荐
- Please configure Spring facet or use 'Create Default Context' to add one including all unmapped files.
有时候我们刚进入 Intellij IDEA时会出现这样一个情况,原因是IDEA没有找到spring的配置文件,我们需要添加spring文件给idea管理 参考: 1.https://www.jetb ...
- Ubuntu+Apache+PHP+Mysql环境搭建(完整版)
Ubuntu+Apache+PHP+Mysql环境搭建(完整版) 一.操作系统Ubuntu 14.04 64位,阿里云服务器 二.Apache 1.安装Apache,安装命令:sudo apt-get ...
- openERP server action,最强大的功能,没有之一
Jeffery9@gmail.com 出品 @jeffery-陈帆 原理 ations OE定义了ir.actions.actions,并从中派生了众多的子类 ir.actions.client ir ...
- mysql: 关于MySQL InnoDB锁行还是锁表?
baidu zone - 关于MYSQL Innodb 锁行还是锁表,深入讲解
- qt的下载链接
http://download.qt.io/archive/qt/5.8/5.8.0/ http://download.qt.io/archive/qt/ http://download.qt.io ...
- oracle sqlplus 常用操作
命令 含义 / 运行 SQL 缓冲区 ? [关键词] 对关键词提供 SQL 帮助 @[@] [文件名] [参数列表] 通过指定的参数,运行指定的命令文件 ACC[EPT] 变量 [DEF[AULT] ...
- CSS入门学习
一.What? CSS的全称是CascadingStyle Sheet,汉语意思是"级联样式表".通常又称为"风格样式表(StyleSheet)".它是用来进行 ...
- asyncio协程与并发
并发编程 Python的并发实现有三种方法. 多线程 多进程 协程(生成器) 基本概念 串行:同时只能执行单个任务 并行:同时执行多个任务 在Python中,虽然严格说来多线程与协程都是串行的,但其效 ...
- 解决Linq.ToDictionary()时的键重复问题
今天在使用 Linq 的 ToDictionary() 时发生了异常,提示: System.ArgumentException: 已添加了具有相同键 因为以前一直没有遇到有相同键的情况,所以从来没关注 ...
- EasyDarwin开源流媒体服务器低延时直播之转发缓存跟进算法
前言 前一段时间,我们为EasyDarwin实现了客户端快速显示画面/听到同步声音的缓存关键帧检索方案,具体的实现方法分别在<EasyDarwin手机直播是如何实现的快速显示视频的方法>和 ...