[IOI2018] werewolf 狼人 题解

在Pycharm中配置Pyqt5工具(2023年新版教程) 在Pycharm中配置Pyqt5相关的三个工具:QtDesigner、PyUIC、PYRCC 阅读详情

[IOI2018] werewolf 狼人

[IOI2018] werewolf 狼人

可以考虑到每一条边能否通过对于人形态来说,取决于两点的最小值,对于狼形态来说取决两点的最大值。

那么我们不妨考虑将两条边的边权定为上述两者,这样就有两张联通的无向图,我们考虑既然不考虑路程的限制我们一个肯定是需要考虑最大生成树另外一个就是最小生成树。

使用 K r u s c a l \tt Kruscal Kruscal 重构树建立两棵树,一个是大根堆另一个是小根堆。

对于两个 x , y x, y x,y 能否到达取决于是否存在一个点同时是两者的儿子。

我们考虑维护 d f s \tt dfs dfs 序,通过可持久化线段树来判断。

但是题目中还有 L , R L, R L,R 的限制,我们考虑到对于一条路径我们其实对于树上一个点还能向上走,我们考虑倍增跳到一个最高的合法的位置进行上述判断即可。

#include <bits/stdc++.h>
using namespace std;

template <typename T>
void r1(T &x) {
    x = 0;
    char c(getchar());
    int f(1);
    for(; c < '0' || c > '9'; c = getchar()) if(c == '-') f = -1;
    for(; '0' <= c && c <= '9';c = getchar()) x = (x * 10) + (c ^ 48);
    x *= f;
}

template <typename T,typename... Args> inline void r1(T& t, Args&... args) {
    r1(t);  r1(args...);
}

//#define int long long
const int maxn = 2e5 + 5;
const int maxm = maxn << 1;

int fa[maxn];
int getfa(int x) {
    return x == fa[x] ? x : fa[x] = getfa(fa[x]);
}

int head[maxn], cnt;
struct Edge {
    int to, next;
}edg[maxn << 2];
void add(int u,int v) {
    edg[++ cnt] = (Edge) {v, head[u]}, head[u] = cnt;
}

vector<int> vc1[maxn], vc2[maxn];

void add(vector<int> *vc,int u,int v) {
    vc[u].push_back(v);
}

void merge(int u,int v) {
    u = getfa(u), v = getfa(v);
    if(u != v)
    fa[u] = v;
}

int n, m, Q;

int d1l[maxn], d1r[maxn], d2l[maxn], d2r[maxn];
int fid[maxn];
int tot1(0), tot2(0);
const int N = 20;
int fa1[maxn][N + 5], fa2[maxn][N + 5];

void dfs1(int p,int pre) {
    d1l[p] = ++ tot1;
    fid[tot1] = p;
    fa1[p][0] = pre;
    for(int i = 1; i <= N; ++ i) fa1[p][i] = fa1[fa1[p][i - 1]][i - 1];
    for(int v : vc1[p]) if(v != pre) dfs1(v, p);
    d1r[p] = tot1;
}

void dfs2(int p,int pre) {
    d2l[p] = ++ tot2;
    fa2[p][0] = pre;
    for(int i = 1; i <= N; ++ i) fa2[p][i] = fa2[fa2[p][i - 1]][i - 1];
    for(int v : vc2[p]) if(v != pre) dfs2(v, p);
    d2r[p] = tot2;
}

int rt[maxn];
int lsn[maxn * 25], rsn[maxn * 25], t[maxn * 25];

struct Seg {
    #define ls lsn[p]
    #define rs rsn[p]
    #define mid ((l + r) >> 1)
    int tot;
    Seg(void) { tot = 0; }
    void Insert(int &p,int pre,int l,int r,int pos) {
        p = ++ tot; t[p] = t[pre], ls = lsn[pre], rs = rsn[pre];
        ++ t[p];
        if(l == r) return ;
        if(pos <= mid) Insert(ls, lsn[pre], l, mid, pos);
        else Insert(rs, rsn[pre], mid + 1, r, pos);
    }
    int ask(int p,int l,int r,int ll,int rr) {
        if(!p) return 0;
        if(ll <= l && r <= rr) return t[p];
        int res(0);
        if(ll <= mid) res += ask(ls, l, mid, ll, rr);
        if(mid < rr) res += ask(rs, mid + 1, r, ll, rr);
        return res;
    }
}T;

int findpre1(int x,int v) {
    for(int i = N; i >= 0; -- i) if(fa1[x][i] >= v && fa1[x][i] != 0) x = fa1[x][i];
    return x;
}

int findpre2(int x,int v) {
    for(int i = N; i >= 0; -- i) if(fa2[x][i] <= v && fa2[x][i] != 0) x = fa2[x][i];
    return x;
}

signed main() {
//    freopen("S.in", "r", stdin);
    int i, j;
    r1(n, m, Q);
//    puts("ZZZZ");
    for(i = 1; i <= m; ++ i) {
        int u, v; r1(u, v);
        ++ u, ++ v;
        add(u, v), add(v, u);
    }
    for(i = 1; i <= n; ++ i) fa[i] = i;
    for(i = n; i >= 1; -- i) {
        for(int j = head[i];j;j = edg[j].next) {
            int to = edg[j].to; if(getfa(to) > i) {
                add(vc1, i, getfa(to));
                merge(to, i);
            }
        }
    }
    for(i = 1; i <= n; ++ i) fa[i] = i;
    for(i = 1; i <= n; ++ i) {
        for(int j = head[i];j;j = edg[j].next) {
            int to = edg[j].to; if(getfa(to) < i) {
                add(vc2, i, getfa(to));
                merge(to, i);
            }
        }
    }
    dfs1(1, 0);
    dfs2(n, 0);
    for(i = 1; i <= n; ++ i)
        T.Insert(rt[i], rt[i - 1], 1, n, d2l[fid[i]]);
    while(Q --) {
        int x, y, l, r;
        r1(x, y, l, r);
        ++ x, ++ y, ++ l, ++ r;
        int nx = findpre1(x, l), ny = findpre2(y, r);
//        printf("%d %d\n", nx, ny);
        int ans = T.ask(rt[d1r[nx]], 1, n, d2l[ny], d2r[ny]) - T.ask(rt[d1l[nx] - 1], 1, n, d2l[ny], d2r[ny]);
//        printf("ans = %d\n", ans);
        if(ans > 0) puts("1");
        else puts("0");
    }
    return 0;
}

/*
6 6 3
5 1
1 2
1 3
3 4
3 0
5 2
4 2 1 2
4 2 2 2
5 4 3 4
*/

Simulink标定工作流优化:当A2L文件遇到ELF,如何用Matlab脚本打通‘最后一公里’? 本文探讨了Simulink标定工作流中A2L与ELF文件处理的自动化解决方案。通过Matlab脚本实现A2L文件智能合并与ELF文件自动匹配,解决了传统手动操作效率低下和易出错的问题,显著提升汽车ECU开发效率。重点介绍了脚本实现细节及持续集成系统集成方案。 阅读详情

相关推荐

Modbus4J vs EasyModbus4J:哪个Java库更适合你的工业项目?

本文深入对比了Java领域两大Modbus通信库Modbus4J与EasyModbus4J。Modbus4J设计稳健、类型安全,适合复杂业务集成;EasyModbus4J基于Netty,在高并发场景下性能更优。文章从架构、性能、API及生产环境多维度分析,为工业物联网项目选型提供决策依据。

weixin_28475533的博客 312

[IOI2018] werewolf 狼人(Kruskal重构树 + 主席树)

这是个经典问题,我们首先可以拍成dfs序,然后映射过去,然后相当于是判断一个区间是否有。首先,我们肯定要建两棵Kruskal重构树的,然后判两棵子树是否有相同编号节点。内的数,直接主席树即可。

zhangtingxiqwq的博客 549

【汽车ECU电控数据管理篇】A2L文件在ECU标定中的关键作用与实战解析

本文深入解析A2L文件在汽车ECU标定中的关键作用,详细介绍了其作为'数据字典'的核心功能与实战应用。通过剖析A2L文件的结构、关键标签及常见问题,帮助工程师高效管理电控数据,提升ECU标定效率与准确性。文章特别强调了ASAP2标准下的A2L文件在汽车电控系统中的重要性。

a3b4c5的博客 789

[IOI2018]werewolf狼人 题解

传送门 由于LOJ真的很慢(不知道是LOJ的问题还是我电脑的问题),这里提供洛谷的传送门,代码是完整代码而不是交互代码 从SSS出发,只经过编号大于等于LLL的点,能够到达的所有点构成的集合记为AAA; 从EEE出发,只经过编号小于等于RRR的点,能够到达的所有点构成的集合记为BBB, 那么就是要求A∩BA\cap BA∩B是否为空集。 自然想到kruskal重构树,先对每条边以两个端点的编号较小...

GKxx 452

AI 代码生成工具的质量评估体系

基础需求层包括响应速度(Response Time)和界面友好性(UI Friendliness),期望需求层涵盖智能提示(Smart Suggestions)和个性化配置(Personalization),兴奋需求层则涉及多模态交互(Multimodal Interaction)和代码进化(Code Evolution)。在金融领域,代码审计合规性(Compliance Audit)权重应提升至40%,而在Web开发中,API兼容性(API Compatibility)的权重需达到35%。

2503_92418637的博客 3375

hwasan / asan详细分析踩内存之一:Use after free

UAF漏洞全称为use after free ,即利用已经被free掉的堆块被再次利用,该漏洞的存在是因为程序编写者在free堆块部分没有将该堆块的fd指针改为0,进而导致该堆块可以被申请回来,3.内存块被free后,其对应的指针没有被设置为 NULL,但是在它下一次使用之前,有代码对这块内存进行了修改,那么当程序再次使用这块内存时,就很有可能会出现奇怪的问题。2.堆块free后,对应指针没有被设置为NULL,即还可以调用会该堆块,当我们申请一个比该堆块小于等于的size时。

1398

HDU 6370 Werewolf 题解(并查集+图论+DFS)

题意简述 一群人玩♂游♂戏。游戏中有两种人,村民和狼人,村民只会说真话,狼人随便(真或假均珂)。给定一些关系,表示第iii个玩家说第jjj个玩家是狼人/村民。请分别找出确定是村民/狼人的个数。 数据 输入 多组数据。第一行是一个TTT,表示有TTT组数据。每组数据中有一个n(n&lt;=105)n(n&lt;=10^5)n(n<=105),表示有多少人。接下来nnn行,第ii...

LightningUZ的博客 349

OMAPL138使用UPP读写测试

UPP测试代码 #include "hw_types.h" // 宏命令 #include "hw_syscfg0_OMAPL138.h" // 系统配置模块寄存器 #include "soc_OMAPL138.h" // DSP C6748 外设寄存器 #include "psc.h" // 电源与睡眠控制宏及设备抽象层函数声明 #include "interrupt.h" // DSP C6748 中断相关应用程序接...

wangjie36的博客 1193

【LOJ2865】「IOI2018」狼人

【题目链接】 点击打开链接 【思路要点】 问题等价于从起点出发只经过 L,L+1,L+2,...,NL,L+1,L+2,...,NL,L+1,L+2,...,N 能够到达的点和终点出发只经过 1,2,3,...,R1,2,3,...,R1,2,3,...,R 能够到达的点是否有交。 建出原图的最小/最大生成树的 KruskalKruskalKruskal ...

cz_xuyixuan的博客 1072

CAN 通信测试工具 canutils

概述 CAN,Controller Area Network,控制器局域网,一种高可靠性的现场总线。广泛用于汽车电子、工业控制通信。 canutils 工具包内含 5 个独立的程序:canconfig、candump、canecho、cansend、cansequence。这几个程序的功能简述如下: canconfig:用于配置 CAN 总线接口的参数,主要是波特率和模式。 candump...

一个软件工程师的技术笔记 1万+

基于Simulink的电机驱动逆变器仿真

本文完成了电机驱动逆变器的Simulink多层级仿真平台搭建,实现了:✅ 构建了从理想到器件级的逆变器模型体系✅ 实现了Si/SiC损耗精确计算与结温预测✅ 建模了母线寄生参数、死区效应、栅极驱动等关键非理想特性✅ 支持故障注入与保护策略验证✅ 集成了热管理、EMI、寿命预测与碳足迹评估。

amy_mhd的博客 88

[IOI2018]狼人

嘟嘟嘟 好题好题。 看到对边权或点权的限制,可以想kruskal重构树(好吧我是为了刷kruskal重构树才写这道题的……)。 给题目变个型:\(Q\)组询问,每组询问为:一匹狼从终点出发,一个人从起点出发,狼只能经过编号为\([1, R]\)的点,人只能经过\([L, n]\)的点,问能否有一个公共点。 那么我们可以给狼和人分别建一棵kruskal重构树,对于人,我们把边权按\...

weixin_30404405的博客 154

Android日志实战——车机日志获取(十五)

这个项目中的 Log 管理系统,其实只是将系统原生 Log 进行输出并导出,并没有太复杂的操作。还有一种 Log 管理系统需要对 Android 原生 Log 系统进行重写,例如我们使用 Log.d(tag, msg) 打印 Log,需要我们根据 tag 信息将不同模块的 Log 数据写入不同的本地文件下,这样可以方便不同模块查看自己的 Log,追踪异常问题。

小旭的专栏 3780

[IOI2018]werewolf狼人

好像很久没更博客了呢~ [IOI2018]werewolf狼人 题目链接 洛谷 题解 可以将题意转化为 求从\(S\)出发只经过大于\(L\)的点构成的集合\(∩\)从\(E\)只经过小于\(R\)的点是否为空。 我们建\(2\)颗\(kruskal\)重构树\(A,B\)。 \(A\)为每条边的两个点中取较小的点为权值所构成的最大生成树对应的重构树。 \(B\)为每条边的两个点中取较大...

dichanpan2699的博客 296

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

[IOI2018] werewolf 狼人

[IOI2018] werewolf 狼人 IOI2018题解 (其实原题强制在线,要用主席树) 代码: 注意: 1.下标从0~n-1 2.kruskal重构树开始有n个节点,tot从n开始,++tot #include<bits/stdc++.h> #define reg register int #define il inline #define numb ...

weixin_34393428的博客 154

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

IOI2018题解

只有部分题解 练习赛 T2 自然还是要简单考虑了 0~n-1的排列,考虑相对的大小 我们先考虑对于前三个:a,b,c 询问a,b,询问b,c,再询问a,b,c 发现,如果三个知道两个,那么第三个可以唯一确定 所以分情况讨论一下: 1.a>b,不妨钦定a=n-1,然后得到a,b,c的值,再询问(c,d),(b,c,d)。。。就可以得到所有的值 2.a<b,不...

weixin_34323858的博客 655

[Luogu4899][IOI2018] werewolf 狼人

luogu sol \(\mbox{IOI2018}\)的出题人有没有看过\(\mbox{NOI2018}\)的题目呀。。。 \(\mbox{Kruskal}\)重构树+二维数点。 题目相当于是问你从\(S\)出发只经过\(\ge L\)的点,和从\(T\)出发只经过\(\le R\)的点有没有交集。 分别建两棵最大/最小\(\mbox{Kruskal}\)重构树,这样从\(S\)出发,...

abcyan1235的博客 170

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

[IOI2018] werewolf 狼人 LG传送门 kruskal重构树好题。 日常安利博客文章 这题需要搞两棵重构树出来,这两棵重构树和我们平时见过的重构树有点不同(据说叫做点权重构树?),根据经过我们简化的建树方法,这两棵树不再是二叉树,但是仍具有kruskal重构树的优秀性质,建议结合后面的描述理解。 看这题需要首先我们从\(S\)走到\(T\)转化为分别从\(S\)和\(T\)出发寻找...

weixin_30881367的博客 150

LG P4899 [IOI2018] werewolf 狼人(kruskal重构树,二维数点)

LG P4899 [IOI2018] werewolf 狼人 Solution 我们发现010101限制长这样子: ∃x(minids−>x≥L    &    maxidx−>e≤R)→1\exist_x(min_{id_{s->x}}\geq L\;\;\And\;\;max_{id_{x->e}}\leq R) \to 1∃x​(minids−>x​​≥L&maxidx−>e​​≤R)→1 因此我们只需要快速求出xxx沿着≥L\geq L≥L的编号能

xmr_pursue_dreams的博客 448

P4899 [IOI2018] werewolf 狼人(kruskal 重构树 + 主席树)

P4899 [IOI2018] werewolf 狼人 给定一个有nnn个点mmm条边的无向图,有QQQ个询问 每次输入S,E,L,RS, E, L, RS,E,L,R,表示你在SSS点出发,要到EEE点,且初始时你是人形态,你只能走[L,n][L, n][L,n]的点, 但是我们要以狼的形态走到终点,这个时候只能走[1,R][1, R][1,R]之间的点, 也就是说我们要在[L,R][L, R][L,R]的某个点变身,问能否从S−>ES->ES−>E。 一个比较容易想到的做法: 显然,初

lifehappy 2730

[Luogu P4899] [LOJ 2865] [IOI2018] werewolf 狼人

洛谷传送门 LOJ传送门 题目描述 在日本的茨城县内共有 NNN 个城市和 MMM 条道路。这些城市是根据人口数量的升序排列的,依次编号为 000 到 N−1N - 1N−1。每条道路连接两个不同的城市,并且可以双向通行。由这些道路,你能从任意一个城市到另外任意一个城市。 你计划了 QQQ 个行程,这些行程分别编号为 000 至 Q−1Q - 1Q−1。第 $i(0 \leq i \leq Q -...

LPA的博客 456

p4899 [IOI2018] werewolf 狼人

分析 我用的主席树维护qwq 代码 #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<cctype> #include<cmath&gt...

weixin_30430169的博客 208

【IOI 2018】Werewolf 狼人

虽然作为IOI的Day1T3,但其实不是一道很难的题,或者说这道题其实比较套路吧。 接下来讲解一下这个题的做法: 如果你做过NOI 2018的Day1T1,并且看懂了题面,那你很快就会联想到这道题,因为两者都是问某一个点能到达的点集,只不过限制在点上还是边上的问题。 $Kruskal$重构树可以把在边上的限制转化成点上的,于是能解决NOI 2018的Day1T1;那么这道题就可以直接做,因...

weixin_30497527的博客 170

P4899-[IOI2018]werewolf 狼人【Kruskal重构树,主席树】

正题 题目链接:https://www.luogu.com.cn/problem/P4899 题目大意 nnn个点的一张无向图,每次询问(s,t,l,r)(s,t,l,r)(s,t,l,r)表示询问能否找到一条s∼ts\sim ts∼t的路径使得该路径可以分割成点的序号在[l,n][l,n][l,n]和[1,r][1,r][1,r]的两段。 解题思路 首先对原图构造两棵KruskalKruskalKruskal生成树,分别是最小序号最大的和最大序号最小的路径,然后我们每次询问是可以分别在树上跳到一个最高

QuantAsk 1284

洛谷4899 IOI2018 werewolf狼人 Kruskal重构树 倍增 线段树合并

题目链接 题意: 给你一个n个点m条边的无向图,每个点的点权就是它的编号,编号是从0到n-1的,有q次询问,每次问两个点是否能在要求下从起点到达终点,要求是,你可以选择路径上的一个点(可以是起点或者终点),使得起点到这个点之前不能走编号小于l的点,在这之后不能走编号大于r的点。n,m,q都是10510^5105量级的。 说明一下,这题本来是个交互题,但是由于洛谷现在并不支持的样子,于是就成立一个传...

forever_shi的博客 382
上一篇: Hdu6355 Fireflies 题解
下一篇: [NOI2018] 归程 题解
sharp_legendgod
博客等级 码龄7年 8粉丝 114原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值