Tunnel Warfare

本文探讨了在抗日战争期间,华北平原上利用隧道进行的游击战。详细描述了村庄通过隧道相连的方式,以及入侵者破坏隧道后,八路军司令部如何请求最新的村庄连接状态。文章涉及单点修改、线段树合并和查询等算法,旨在快速重建被破坏的隧道连接,确保村庄间的有效通信。

Description

During the War of Resistance Against Japan, tunnel warfare was carried out extensively in the vast areas of north China Plain. Generally speaking, villages connected by tunnels lay in a line. Except the two at the ends, every village was directly connected with two neighboring ones.

Frequently the invaders launched attack on some of the villages and destroyed the parts of tunnels in them. The Eighth Route Army commanders requested the latest connection state of the tunnels and villages. If some villages are severely isolated, restoration of connection must be done immediately!

Input

The first line of the input contains two positive integers n and m (n, m 50,000) indicating the number of villages and events. Each of the next m lines describes an event.

There are three different events described in different format shown below:

  1. D x: The x-th village was destroyed.
  2. Q x: The Army commands requested the number of villages that x-th village was directly or indirectly connected with including itself.
  3. R: The village destroyed last was rebuilt.

Output

Output the answer to each of the Army commanders request in order on a separate line.

Sample Input

7 9
D 3
D 6
D 5
Q 4
Q 5
R
Q 4
R
Q 4

Sample Output

1
0
2
4

Hint

An illustration of the sample input:

      OOOOOOO

D 3   OOXOOOO

D 6   OOXOOXO

D 5   OOXOXXO

R     OOXOOXO

R     OOXOOOO


题解:线段树合并,单点修改。查询的时候先在节点的中间连续部分去找,如果中间不连续,说明连续部分不在左孩子就在右孩子,因为左右孩子不可能连在一起(也就是断开的),如果连续,可能在该部分,如果不在,说明在孩子里面。画图解决。


#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

struct Node
{
	int l,r;
	int ls,rs,ms;
};

Node arr[200005];
int d[50004];
int k;

void pushUp(int k)
{
	int li = k << 1;
	int ri = (k << 1) | 1;
	arr[k].ls = arr[li].ls;
	arr[k].rs = arr[ri].rs;
	arr[k].ms = 0; 
	if(arr[li].rs != 0 && arr[ri].ls != 0)
	{
		arr[k].ms = arr[li].rs + arr[ri].ls;
		if(arr[li].ls == arr[li].r - arr[li].l + 1)
		{
			arr[k].ls += arr[ri].ls;
		}
		if(arr[ri].rs == arr[ri].r - arr[ri].l + 1)
		{
			arr[k].rs += arr[li].rs;
		}
	}
}

void segTree(int k,int l,int r)
{
	arr[k].l = l;
	arr[k].r = r;
	if(l == r)
	{
		arr[k].ls = arr[k].rs = arr[k].ms = 1;
		return;
	}
	int mid = (l + r) >> 1;
	segTree(k << 1,l,mid);
	segTree((k << 1) | 1,mid + 1,r);
	pushUp(k);
}

void update(int k,int x,int y)
{
	if(arr[k].l == arr[k].r)
	{
		arr[k].ls = y;
		arr[k].rs = y;
		arr[k].ms = y;
		return;
	}
	int mid = (arr[k].l + arr[k].r) >> 1;
	if(x <= mid)
	{
		update(k << 1,x,y);
	}
	else
	{
		update((k << 1) | 1,x,y);
	}
	pushUp(k);
}

int query(int k,int x)   //不在中间(说明对于该点两个孩子没有相交部分)就在孩子里面, 
{
	if(arr[k].l == arr[k].r)
	{
		return arr[k].ls;
	}
	int mid = (arr[k].l + arr[k].r) >> 1; 
    if(arr[k].ms != 0)
	{
		if(x > arr[k << 1].r - arr[k << 1].rs && x < arr[(k << 1) | 1].l + arr[(k << 1) | 1].ls)
		{
			return arr[k].ms;
		}
	} 
	if(x <= mid)
	{
		return query(k << 1,x);
	}
	return query((k << 1) | 1,x);
}

int main()
{
	int n,m;
	while(scanf("%d%d",&n,&m) != EOF)
	{
		char s[3];
		int x;
		k = 0;
		segTree(1,1,n);
		while(m--)
		{
			scanf("%s",s);
			if(s[0] == 'D')
			{
				scanf("%d",&x);
				d[k++] = x;
				update(1,x,0);
			}
			else if(s[0] == 'R')
			{
				update(1,d[--k],1);
			}
			else
			{
				scanf("%d",&x);
				printf("%d\n",query(1,x));
			}
		}
	}
	
	
	return 0;
 } 


<think>好的,我需要帮助用户深入了解Tunnel技术,特别是GRE Tunnel的实现原理和技术细节。用户已经提供了之前的对话历史,其中详细解释了GRE技术,并通过快递隧道的比喻进行了说明。现在用户想进一步了解Tunnel相关的技术细节或实现方式,尤其是GRE Tunnel的原理。 首先,回顾之前的回答,用户已经了解了GRE的基本工作原理、封装过程、应用场景以及优缺点。现在需要更深入地探讨技术实现,可能需要包括封装的详细步骤、协议头结构、配置示例以及与其他技术的对比。 用户提供的参考引用提到了OSPF与GRE Tunnel的配置命令,但用户现在更关注的是Tunnel技术本身的详解,而不是具体配置。因此,我需要集中讨论GRE Tunnel的实现机制,例如封装过程、协议号、头部字段的作用,以及可能涉及的MTU问题、安全性考虑等。 需要注意用户提到的站内引用[1]中的信息,确保引用相关内容,如GRE的多协议封装能力、隧道端点处理流程等。同时,用户希望尽可能参考之前的回答,因此需要保持比喻的一致性,比如继续使用快递隧道的类比来解释技术细节。 接下来,我需要组织内容,使其结构清晰,分点阐述。可能的结构包括:封装解封装流程、协议头结构、关键技术点(如协议号47、密钥验证、Keepalive机制)、与其他隧道协议的比较、典型应用场景中的技术实现,以及常见问题如MTU调整和故障排查。 还需要确保使用正确的中文术语,避免技术术语错误,同时保持解释的通俗易懂,符合用户之前接受的快递隧道比喻。此外,根据用户要求,所有行内数学表达式和独立公式需使用正确的LaTeX格式,但在这个主题中可能涉及的数学内容较少,更多是协议结构描述,因此需注意正确使用代码块和表格来展示技术细节。 最后,生成相关问题时要围绕用户可能感兴趣的扩展点,如GRE与IPSec的结合、与其他隧道技术的对比、性能优化等,确保问题具有针对性,帮助用户进一步探索。</think>### GRE Tunnel技术详解及实现原理 --- #### **一、Tunnel技术基础概念** 1. **隧道本质** - 逻辑上的**点对点直连通道**,物理上通过封装/路由实现,如: $$原始数据包 \xrightarrow{封装} [外层IP头][隧道协议头][原始数据]$$ - 类比:快递员将**异形包裹**装入标准纸箱(外层协议),确保跨区域运输[^1]。 2. **核心功能** - **协议转换**:支持IPv4/IPv6、IPX等异构协议互传 - **逻辑隔离**:在公共网络(如互联网)上构建私有数据通道 - **路径控制**:强制数据流经指定路径(如绕过防火墙策略) --- #### **二、GRE Tunnel实现原理** 1. **封装结构拆解** ```plaintext | 外层IP头部 (20B) | GRE头部 (4-16B) | 原始数据包 | ``` - **外层IP头**:源/目的地址为隧道两端接口IP(如`10.1.1.1 → 203.0.113.5`) - **GRE头**:包含协议类型、校验标识、密钥等关键字段(详见下表) | 字段 | 长度 | 功能说明 | |-----------------|-------|---------------------------------| | Flags/Version | 2 bits| 标识是否启用校验和/密钥(如`0x8000`启用密钥) | | Protocol Type | 16 bits| 原始数据协议类型(如`0x0800`=IPv4)[^3] | | Checksum/Offset | 可选 | 数据完整性校验(RFC2890扩展) | | Key | 4B | 隧道两端匹配的认证密钥 | 2. **协议交互流程** ```mermaid graph LR A[原始数据包] --> B{GRE封装} B -->|添加GRE头+外层IP头| C[GRE报文] C --> D[公网路由传输] D --> E{GRE解封装} E --> F[还原原始数据] ``` 3. **关键技术特性** - **协议号47**:IP头部`Protocol`字段值为47时标识GRE报文[^3] - **PMTU发现**:通过设置DF位避免分片,动态调整隧道接口MTU(默认1476字节) - **防环路机制**:隧道接口丢弃源IP属于本地的数据包(通过ACL实现) --- #### **三、典型实现方式(以Cisco设备为例)** ```cisco ! 创建Tunnel接口 interface Tunnel0 ip address 192.168.1.1 255.255.255.0 tunnel source 203.0.113.1 ! 隧道起点公网IP tunnel destination 198.51.100.2 ! 隧道终点公网IP tunnel mode gre ip ! 指定GRE over IP模式 keepalive 10 3 ! 每10秒发送Keepalive,3次失败判定隧道中断 ``` --- #### **四、进阶技术细节** 1. **分片处理逻辑** - 原始数据包超过PMTU时: - 若DF=1 → 丢弃并返回ICMP Fragmentation Needed - 若DF=0 → 外层IP分片传输,接收端重组后解封装 2. **QoS优先级继承** ```plaintext 外层IP头ToS字段 = 原始IP头ToS值 & 0xFC // 保留前6位优先级标记 ``` 3. **多协议支持原理** - **协议类型字段**:GRE头部`Protocol Type`标识原始数据协议(如`0x0800`=IPv4,`0x86DD`=IPv6) - **嵌套隧道**:GRE隧道内可承载其他隧道协议(如GRE over IPSec over MPLS) --- #### **五、与其他隧道技术对比** | 特性 | GRE | IPSec隧道模式 | VXLAN | |---------------------|-------------------|-------------------|------------------| | **封装开销** | 24-36B | 50-57B | 50B+ | | **协议支持** | 多协议 | 仅IP | 仅以太网帧 | | **安全性** | 无加密 | 强加密 | 依赖叠加层 | | **典型场景** | 跨协议互联 | 安全远程接入 | 数据中心大二层扩展 | --- ### 相关问题 1. GRE如何通过Key字段实现隧道端点认证?[^2] 2. 在MPLS网络中为何需要GRE隧道嵌套? 3. GRE Keepalive机制如何检测隧道中断? 4. 为何GRE不适合直接传输实时音视频流? [^1]: GRE通过外层IP头实现跨网络路由,原始协议数据被完全封装保护。 [^2]: Key字段提供简单的隧道端点验证,但需配合IPSec实现完整安全保障。 [^3]: 协议号47使得中间路由设备能正确识别并转发GRE报文。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值