【luogu3733】【HAOI2017】 八纵八横 (线段树分治+线性基)

本文介绍了一个复杂图论问题的解决方案:在一个动态变化的带重边自环的图中,实时更新并求出通过特定节点的所有环路抑或值的最大值。通过构建生成树和使用线性基数据结构,结合离线查询和线段树分治策略,实现了高效的算法设计。

Descroption

原题链接 给你一个\(n\)个点的图,有重边有自环保证连通,最开始有\(m\)条固定的边,要求你支持加边删边改边(均不涉及最初的\(m\)条边),每一次操作都求出图中经过\(1\)号点的环的抑或值的最大值,每个节点或边都可以经过多次(一条路经过多次则会被计算多次)。

Solution

\(~~~~\)好久都没发过博客了一定是我改题如蜗牛哎。对于每一次操作都要输出答案,考虑用线段树分治离线。先在图中随便弄出一颗以\(1\)为根的生成树,若之后再加了一条边\((u, ~v)~\)(这时一定成环便可以统计答案了),则在线性基插入一个\(~dis[v] ~xor ~dis[u] ~xor~ w_{u, v}\),对于三种操作,维护每条边作为该权值的起止时间,最后在线段树中统计答案就行了。这道题让我知道了我以前打的一直是假的线性基qwq %%%Rudy!!!

Code

#include <bits/stdc++.h>
#define For(i, j, k) for (register int i = j; i <= k; ++i)
#define Forr(i, j, k) for (register int i = j; i >= k; --i)
#define Travel(i, u) for (register int i = beg[u], v = to[i]; i; v = to[i = nex[i]])
using namespace std;

inline int read() {
    int x = 0, p = 1; char c = getchar();
    for (; !isdigit(c); c = getchar()) if (c == '-') p = -1;
    for (; isdigit(c); c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
    return x * p;
}

inline void File() {
    freopen("luogu3733.in", "r", stdin);
    freopen("luogu3733.out", "w", stdout);
}

const int N = 1e3 + 5; typedef bitset<N> BI;
int e = 1, beg[N], nex[N], to[N], n, m, q, fa[N];
BI w[N], dis[N];

inline BI get() {
    static char s[N]; BI res; res.reset();
    scanf("%s", s); int len = strlen(s);
    For(i, 0, len - 1) res[i] = s[len - 1 - i] - '0';
    return res;
}

inline void write(BI t) {
    static int p;
    Forr(i, N - 5, 0) if (t[i]) { p = i; break; }
    Forr(i, p, 0) putchar(t[i] + '0'); puts("");
}

struct Linear_Bases {
    BI p[N];    
    inline void insert(BI t) {
        Forr(i, N - 5, 0) if (t[i]) {
            if (!p[i].any()) { p[i] = t; return; }
            t ^= p[i];
        }
    }
    inline BI maxv() {
        BI res; res.reset();
        Forr(i, N - 5, 0) if (!res[i]) res ^= p[i]; 
        return res;
    }
} T;

struct node { int u, v, l, r; BI w; } P[N << 1]; int cnt = 0;

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

inline void add(int x, int y, BI z) {
    to[++ e] = y, nex[e] = beg[x], w[beg[x] = e] = z;
    to[++ e] = x, nex[e] = beg[y], w[beg[y] = e] = z;
}

inline void dfs(int u, int f) {
    Travel(i, u) if (v ^ f) dis[v] = dis[u] ^ w[i], dfs(v, u);
}

#define lc (rt << 1)
#define rc (rt << 1 | 1)
#define mid (l + r >> 1)
vector<int> ve[N << 2];

inline void update(int rt, int l, int r, int L, int R, int v) {         
    if (L <= l && r <= R) return (void) (ve[rt].push_back(v));
    if (L <= mid) update(lc, l, mid, L, R, v);
    if (R > mid) update(rc, mid + 1, r, L, R, v);
}

inline void query(int rt, int l, int r, Linear_Bases T) {
    for (int v : ve[rt]) T.insert(dis[P[v].u] ^ dis[P[v].v] ^ P[v].w);
    if (l == r) return (void) (write(T.maxv()));
    query(lc, l, mid, T), query(rc, mid + 1, r, T); 
}       

int lst[N];

int main() {
    File();

    n = read(), m = read(), q = read();

    For(i, 1, n) fa[i] = i;
    For(i, 1, m) {
        int fx, fy, u = read(), v = read(); BI z = get();
        fx = find(u), fy = find(v);
        if (fx ^ fy) add(u, v, z), fa[fy] = fx;
        else P[++ cnt] = (node) {u, v, 0, q, z};
    }

    dfs(1, 0);

    static char s[8]; // <--- SKT_T1_Faker's Dream Way!
    for (register int i = 1, u, v, tt = 0; i <= q; ++ i) {
        scanf("%s", s);         

        if (s[1] == 'd') {
            u = read(), v = read(); BI z = get();
            P[lst[++ tt] = ++ cnt] = (node) {u, v, i, q, z};    
        
        } else if (s[1] == 'h') {
            v = lst[u = read()]; BI z = get(); P[v].r = i - 1;
            P[lst[u] = ++ cnt] = (node) {P[v].u, P[v].v, i, q, z};
        
        } else v = lst[u = read()], P[v].r = i - 1, lst[u] = -1;
    }   

    For(i, 1, cnt) update(1, 0, q, P[i].l, P[i].r, i);
    query(1, 0, q, T);

    return 0;
}

转载于:https://www.cnblogs.com/LSTete/p/9710066.html

内容概要:本文档是一份关于交换路由配置的学习笔记,系统地介绍了网络设备的远程管理、交换机与路由器的核心配置技术。内容涵盖Telnet、SSH、Console三种远程控制方式的配置方法;详细讲解了VLAN划分原理及Access、Trunk、Hybrid端口的工作机制,以及端口镜像、端口汇聚、端口隔离等交换技术;深入解析了STP、MSTP、RSTP生成树协议的作用与配置步骤;在路由部分,涵盖了IP地址配置、DHCP服务部署(接口池与全局池)、NAT转换(静态与动态)、静态路由、RIP与OSPF动态路由协议的配置,并介绍了策略路由和ACL访问控制列表的应用;最后简要说明了华为防火墙的安全区域划分与基本安全策略配置。; 适合人群:具备一定网络基础知识,从事网络工程、运维或相关技术岗位1-3年的技术人员,以及准备参加HCIA/CCNA等认证考试的学习者。; 使用场景及目标:①掌握企业网络中常见的交换与路由配置技能,提升实际操作能力;②理解VLAN、STP、OSPF、NAT、ACL等核心技术原理并能独立完成中小型网络搭建与调试;③通过命令示例熟悉华为设备CLI配置逻辑,为项目实施和故障排查提供参考。; 阅读建议:此笔记以实用配置为主,建议结合模拟器(如eNSP或Packet Tracer)动手实践每一条命令,对照拓扑理解数据流向,重点关注VLAN间通信、路由选择机制、安全策略控制等关键环节,并注意不同设备型号间的命令差异。
多旋翼无人机组合导航系统-多源信息融合算法(Matlab代码实现)内容概要:本文围绕多旋翼无人机组合导航系统,重点介绍了基于多源信息融合算法的设计与实现,利用Matlab进行代码开发。文中采用扩展卡尔曼滤波(EKF)作为核心融合算法,整合GPS、IMU(惯性测量单元)、里程计和电子罗盘等多种传感器数据,提升无人机在复杂环境下的定位精度与稳定性。特别是在GPS信号弱或丢失的情况下,通过IMU惯导数据辅助导航,实现连续可靠的位姿估计。同时,文档展示了完整的算法流程与Matlab仿真实现,涵盖传感器数据预处理、坐标系转换、滤波融合及结果可视化等关键环节,体现了较强的工程实践价值。; 适合人群:具备一定Matlab编程基础和信号处理知识,从事无人机导航、智能控制、自动化或相关领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于多旋翼无人机的高精度组合导航系统设计;②用于教学与科研中理解多传感器融合原理与EKF算法实现;③支持复杂环境下无人机自主飞行与定位系统的开发与优化。; 阅读建议:建议结合Matlab代码与理论推导同步学习,重点关注EKF的状态预测与更新过程、多传感器数据的时间同步与坐标变换处理,并可通过修改噪声参数或引入更多传感器类型进行扩展实验。
### 树的直径问题概述 树的直径是指树中最长的简单路径,通常定义为两个节点之间的最大距离。解决树的直径问题的方法主要包括动态规划和贪心算法两种思路。 #### 动态规划方法 动态规划方法中,可以通过两次深度优先搜索(DFS)来求解树的直径。具体步骤如下: 1. 从任意一个节点出发进行一次 DFS,找到距离该节点最远的节点 $ u $。 2. 从节点 $ u $ 再次进行一次 DFS,找到距离 $ u $ 最远的节点 $ v $,路径 $ u \rightarrow v $ 即为树的直径。 在实现过程中,可以维护两个数组 `dp` 和 `dp2`,分别表示从某个节点出发的最长路径和次长路径。通过更新这两个数组,可以计算出经过每个节点的最长路径,并最终找到整个树的最长路径。 ```cpp void dfs(int u, int fa) { for (auto x : g[u]) { if (x == fa) continue; dfs(x, u); f[u] = max(f[u], d[u] + d[x] + 1); d[u] = max(d[u], d[x] + 1); } } ``` #### 贪心方法 贪心方法的核心思想是通过两次 DFS 找到树的直径。第一次 DFS 用于找到距离任意起点最远的节点 $ u $,第二次 DFS 则从 $ u $ 出发找到最远的节点 $ v $。路径 $ u \rightarrow v $ 即为树的最长路径。 这种方法的时间复杂度为 $ O(n) $,适用于大多数树的直径问题。 #### 洛谷 P1099 树网的核问题 在洛谷 P1099 [NOIP2007 提高组] 树网的核问题中,树的直径是核心概念之一。题目要求找到树中的一条路径,使得该路径的长度不超过给定值,并且尽可能多地覆盖树中的节点。树的直径在该问题中起到了关键作用,通常需要结合枚举和树的直径特性进行求解。 #### 树的最长路径算法 树的最长路径算法通常包括以下步骤: 1. **选择起点**:从任意一个节点开始进行 DFS。 2. **寻找最远节点**:通过 DFS 找到距离起点最远的节点 $ u $。 3. **再次寻找最远节点**:从 $ u $ 开始进行第二次 DFS,找到距离 $ u $ 最远的节点 $ v $。 4. **计算直径**:路径 $ u \rightarrow v $ 即为树的直径。 该算法的时间复杂度为 $ O(n) $,适用于大多数树的直径问题。 ### 相关问题 1. 如何通过两次 DFS 找到树的直径? 2. 树的直径问题中的动态规划方法是如何实现的? 3. 洛谷 P1099 树网的核问题中如何应用树的直径特性? 4. 树的最长路径算法的时间复杂度是多少? 5. 如何通过贪心算法解决树的直径问题?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值