Luogu4899 IOI2018 Werewolf 主席树、Kruskal重构树
IOI强行交互可还行,我Luogu的代码要改很多才能交到UOJ去……
发现问题是对边权做限制的连通块类问题,考虑\(Kruskal\)重构树进行解决。
对于图上的边\((u,v)(u<v)\),我们建两棵\(Kruskal\)重构树,一棵按照\(u\)从大到小加边表示人形时的活动区域,一棵按照\(v\)从小到大加边表示狼形时的活动区域。
那么我们的每组询问就变为了:给出两段区间,询问是否存在一个点同时覆盖这两个区间(即人形转换为狼形的地点)。这个是经典的二维数点问题,使用主席树计算即可。
话说感觉一堆namespace的码风看起来好舒服啊~
#include<bits/stdc++.h>
//This code is written by Itst
using namespace std;
inline int read(){
int a = 0;
char c = getchar();
bool f = 0;
while(!isdigit(c)){
if(c == '-')
f = 1;
c = getchar();
}
while(isdigit(c)){
a = (a << 3) + (a << 1) + (c ^ '0');
c = getchar();
}
return f ? -a : a;
}
const int MAXN = 2e5 + 10;
int N , M , Q;
namespace ST{
#define mid ((l + r) >> 1)
struct node{
int l , r , sum;
}Tree[MAXN * 50];
int root[MAXN] , cnt;
void insert(int& x , int p , int l , int r , int tar){
x = ++cnt;
Tree[x] = Tree[p];
++Tree[x].sum;
if(l == r)
return;
if(mid >= tar)
insert(Tree[x].l , Tree[p].l , l , mid , tar);
else
insert(Tree[x].r , Tree[p].r , mid + 1 , r , tar);
}
bool query(int x , int y , int l , int r , int L , int R){
if(Tree[x].sum == Tree[y].sum)
return 0;
if(l >= L && r <= R)
return 1;
bool f = 0;
if(mid >= L)
f |= query(Tree[x].l , Tree[y].l , l , mid , L , R);
if(!f && mid < R)
f |= query(Tree[x].r , Tree[y].r , mid + 1 , r , L , R);
return f;
}
}
namespace Itst{
#define P pair < int , int >
int fa[2][MAXN << 1] , ch[2][MAXN << 1][2] , jump[2][MAXN << 1][21] , que[2][MAXN << 1] , dfn[2][MAXN] , cnt[2] , ts[2] , rg[2][MAXN << 1][2];
void init(){
cnt[0] = cnt[1] = N;
for(int i = 1 ; i <= N ; ++i)
fa[0][i] = fa[1][i] = i;
}
int find(int ind , int x){
return fa[ind][x] == x ? x : (fa[ind][x] = find(ind , fa[ind][x]));
}
inline void link(int ind , int x , int y){
x = find(ind , x);
y = find(ind , y);
if(x == y)
return;
++cnt[ind];
fa[ind][x] = fa[ind][y] = fa[ind][cnt[ind]] = cnt[ind];
ch[ind][cnt[ind]][0] = x;
ch[ind][cnt[ind]][1] = y;
}
void dfs(int ind , int x , int p){
jump[ind][x][0] = p;
for(int i = 1 ; jump[ind][x][i - 1] ; ++i)
jump[ind][x][i] = jump[ind][jump[ind][x][i - 1]][i - 1];
if(x <= N){
rg[ind][x][0] = rg[ind][x][1] = dfn[ind][x] = ++ts[ind];
que[ind][x] = x;
return;
}
dfs(ind , ch[ind][x][0] , x);
dfs(ind , ch[ind][x][1] , x);
que[ind][x] = ind ? min(que[ind][ch[ind][x][0]] , que[ind][ch[ind][x][1]]) : max(que[ind][ch[ind][x][0]] , que[ind][ch[ind][x][1]]);
rg[ind][x][0] = rg[ind][ch[ind][x][0]][0];
rg[ind][x][1] = rg[ind][ch[ind][x][1]][1];
}
int up(int ind , int x , int l , int r){
for(int i = 19 ; i >= 0 ; --i)
if(jump[ind][x][i] && que[ind][jump[ind][x][i]] >= l && que[ind][jump[ind][x][i]] <= r)
x = jump[ind][x][i];
return x;
}
void work(){
dfs(0 , cnt[0] , 0);
dfs(1 , cnt[1] , 0);
vector < P > p;
for(int i = 1 ; i <= N ; ++i)
p.push_back(P(dfn[0][i] , dfn[1][i]));
sort(p.begin() , p.end());
for(int i = 1 ; i <= N ; ++i)
ST::insert(ST::root[i] , ST::root[i - 1] , 1 , N , p[i - 1].second);
while(Q--){
int S = read() + 1 , E = read() + 1 , L = read() + 1 , R = read() + 1;
E = up(0 , E , 1 , R);
S = up(1 , S , L , N);
puts(ST::query(ST::root[rg[0][E][1]] , ST::root[rg[0][E][0] - 1] , 1 , N , rg[1][S][0] , rg[1][S][1]) ? "1" : "0");
}
}
}
namespace init{
struct Edge{
int a , b;
}Ed[MAXN << 1];
bool cmp1(Edge a , Edge b){
return a.b < b.b;
}
bool cmp2(Edge a , Edge b){
return a.a > b.a;
}
void main(){
N = read();
M = read();
Q = read();
Itst::init();
for(int i = 1 ; i <= M ; ++i){
Ed[i].a = read() + 1;
Ed[i].b = read() + 1;
if(Ed[i].a > Ed[i].b)
swap(Ed[i].a , Ed[i].b);
}
sort(Ed + 1 , Ed + M + 1 , cmp1);
for(int i = 1 ; i <= M ; ++i)
Itst::link(0 , Ed[i].a , Ed[i].b);
sort(Ed + 1 , Ed + M + 1 , cmp2);
for(int i = 1 ; i <= M ; ++i)
Itst::link(1 , Ed[i].a , Ed[i].b);
Itst::work();
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in" , "r" , stdin);
//freopen("out" , "w" , stdout);
#endif
init::main();
return 0;
}
Luogu4899 IOI2018 Werewolf 主席树、Kruskal重构树的更多相关文章
- Kruskal重构树入门
这个知识点好像咕咕咕了好长了..趁还没退役赶紧补一下吧.. 讲的非常简略,十分抱歉.. 前置知识 Kruskal算法 一定的数据结构基础(如主席树) Kruskal重构树 直接bb好像不是很好讲,那就 ...
- [IOI2018] werewolf 狼人 kruskal重构树,主席树
[IOI2018] werewolf 狼人 LG传送门 kruskal重构树好题. 日常安利博客文章 这题需要搞两棵重构树出来,这两棵重构树和我们平时见过的重构树有点不同(据说叫做点权重构树?),根据 ...
- [IOI2018] werewolf 狼人 [kruskal重构树+主席树]
题意: 当你是人形的时候你只能走 \([L,N-1]\) 的编号的点(即大于等于L的点) 当你是狼形的时候你只能走 \([1,R]\) 的编号的点(即小于等于R的点) 然后问题转化成人形和狼形能到的点 ...
- UOJ#407. 【IOI2018】狼人 Kruskal,kruskal重构树,主席树
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ407.html 题解 套路啊. 先按照两个节点顺序各搞一个kruskal重构树,然后问题转化成两棵krus ...
- LOJ.2865.[IOI2018]狼人(Kruskal重构树 主席树)
LOJ 洛谷 这题不就是Peaks(加强版)或者归程么..这算是\(IOI2018\)撞上\(NOI2018\)的题了? \(Kruskal\)重构树(具体是所有点按从小到大/从大到小的顺序,依次加入 ...
- 【BZOJ-3545&3551】Peaks&加强版 Kruskal重构树 + 主席树 + DFS序 + 倍增
3545: [ONTAK2010]Peaks Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1202 Solved: 321[Submit][Sta ...
- BZOJ 3551: [ONTAK2010]Peaks加强版 [Kruskal重构树 dfs序 主席树]
3551: [ONTAK2010]Peaks加强版 题意:带权图,多组询问与一个点通过边权\(\le lim\)的边连通的点中点权k大值,强制在线 PoPoQQQ大爷题解传送门 说一下感受: 容易发现 ...
- bzoj 3551 kruskal重构树dfs序上的主席树
强制在线 kruskal重构树,每两点间的最大边权即为其lca的点权. 倍增找,dfs序对应区间搞主席树 #include<cstdio> #include<cstring> ...
- [IOI2018]狼人——kruskal重构树+可持久化线段树
题目链接: IOI2018werewolf 题目大意:给出一张$n$个点$m$条边的无向图,点和边可重复经过,一个狼人初始为人形,有$q$次询问,每次询问要求人形态只能处于编号不小于$L$的点,狼形态 ...
随机推荐
- htmlElement.style 是只读属性
document.getElementById('test').style = 'opacity:0'; 在某些机型上,比如苹果 ios 10机型上,会报错.提示 style 属性为只读属性. 建议所 ...
- NFS共享权限挂载
mount -t nfs 192.168.2.203:/data/lys /lys -o proto=tcp -o nolock mount 172.16.2.18:/home/arcgisserve ...
- 《ASP.NET MVC企业实战》(三)MVC开发前奏
在上一篇“<ASP.NET MVC企业级实战>(二)MVC开发前奏”中跟随作者大概了解了一些C#3.0和3.5中的新特性.本篇继续以这样的方式来学习C#中的一些特性. 一.C#3. ...
- 2018下半年Android面试历程
个人看法:可以总结下他的面试经历以及涉及到的面试题 下面开始正文吧: 从今年下半年以来就开始在杭州准备简历找工作了,原因基本都懂的,没多少工资,投递简历的渠道是Boss,偶尔也在拉钩上投递,刚开始把简 ...
- Android基础之内容提供者的实现
内容提供者可以实现应用间查询数据库的需求 一.在提供数据库访问的应用设置内容提供者 public class AccountProvider extends ContentProvider { sta ...
- 利用python中的gensim模块训练和测试word2vec
word2vec的基础知识介绍参考上一篇博客和列举的参考资料. 首先利用安装gensim模块,相关依赖如下,注意版本要一致: Python >= 2.7 (tested with version ...
- C++基础学习一(基础之基础)
开篇:做了这么多年的软件,第一次使用博客的方式记录学习过程,之前都是笔记本(都有一摞了),因为之前一直从事的都是.NET的开发工作,对C++知之甚少,但一直想了解C++这门鼻祖级的语言,现在终于下定决 ...
- scp 实现远程异地备份
1.先做好脚本 2.再使用crontab 定时执行计划任务 0 1 * * * /usr/bin/expect /root/script/scpautodown.sh #执行,也可先定义环境变量 0 ...
- Linux 下查看系统当前登录用户信息
当你新登录一个主机,过着管理一个主机,这时候你就需要这些命令来进行查看了: 1. w : Show who is logged on and what they are doing. w [optio ...
- cobaltstrike3.8服务器搭建及使用
参考链接: https://www.ezreal.net/archives/166.htmlhttp://blog.cobaltstrike.com/category/cobalt-strike-2/ ...