【洛谷P5385】须臾幻境/【BZOJ3514】Codechef MARCH14 GERALD07加强版【LCT】【主席树】

本文介绍了一种处理大规模图中在线连通性查询的高效算法。针对有n个节点、m条边的图,算法能在O(nlogn)的时间复杂度内处理q次询问,每次询问[L,R]区间内的边连接后的连通块数量。通过使用LCT(Link-Cut Tree)维护最大生成树和主席树进行区间查询,实现了快速响应。

题意:有nnn个点mmm条边,qqq次询问连接区间[L,R][L,R][L,R]中的边后的连通块个数。强制在线。

n,m,q≤2×105n,m,q\leq 2\times10^5n,m,q2×105

显然连通块个数=n−任意一个生成森林的边数连通块个数=n-任意一个生成森林的边数=n

先遍历一遍所有边,用LCT维护标号的最大生成树,并记录下加入每条边iii时删除的边的编号aia_iai(如果没有删除边,ai=0a_i=0ai=0)

询问[L,R][L,R][L,R]时,假装加入了[1,R][1,R][1,R]中的边。对于i∈[L,R]i\in[L,R]i[L,R],如果ai≥La_i\geq LaiL,那么加入iii后会形成一个环,并且环上所有边的编号都在[L,R][L,R][L,R]内,这样iii就没有贡献。

所以只需要询问∑i=LR[ai<L]\sum_{i=L}^R[a_i<L]i=LR[ai<L]即可,用主席树维护

复杂度O(nlog⁡n)O(n\log n)O(nlogn)

注意自环要让ai=m+1a_i=m+1ai=m+1

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <cassert>
#define MAXN 400005
using namespace std;
inline int read()
{
	int ans=0;
	char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans;
}
int n,m;
int u[MAXN],v[MAXN],a[MAXN];
namespace LCT
{
	inline int min(const int& x,const int& y){return x<y? x:y;}
	int ch[MAXN][2],fa[MAXN],rv[MAXN],mn[MAXN];
	inline void update(int x)
	{
		mn[x]=x;
		if (ch[x][0]) mn[x]=min(mn[x],mn[ch[x][0]]);
		if (ch[x][1]) mn[x]=min(mn[x],mn[ch[x][1]]);
	}
	inline void pushr(int x){swap(ch[x][0],ch[x][1]),rv[x]^=1;}
	inline void pushdown(int x)
	{
		if (rv[x])
		{
			if (ch[x][0]) pushr(ch[x][0]);
			if (ch[x][1]) pushr(ch[x][1]);
			rv[x]=0;
		}
	}
	inline bool isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
	inline int get(int x){return ch[fa[x]][1]==x;}
	inline void rotate(int x)
	{
		int y=fa[x],z=fa[y];
		int l=get(x),r=l^1;
		int w=ch[x][r];
		if (!isroot(y)) ch[z][get(y)]=x;
		ch[x][r]=y,ch[y][l]=w;
		if (w) fa[w]=y;
		fa[y]=x,fa[x]=z;
		update(y),update(x);
	}
	int q[MAXN],tp;
	inline void splay(int x)
	{
		q[tp=1]=x;
		for (int i=x;!isroot(i);i=fa[i]) q[++tp]=fa[i];
		for (int i=tp;i>=1;i--) pushdown(q[i]);
		while (!isroot(x))
		{
			int y=fa[x];
			if (!isroot(y))
			{
				if (get(x)==get(y)) rotate(y);
				else rotate(x);
			}
			rotate(x);
		}
	}
	inline void access(int x){for (int y=0;x;y=x,x=fa[x])	splay(x),ch[x][1]=y,update(x);}
	inline void evert(int x){access(x),splay(x),pushr(x);}
	inline int findrt(int x)
	{
		access(x),splay(x);
		while (ch[x][0]) x=ch[x][0],pushdown(x);
		return x;
	}
	inline bool link(int x,int y)
	{
		evert(x);
		if (findrt(y)==x) return false;
		fa[x]=y;
		return true;
	}
	inline void cut(int x,int y)
	{
		evert(x);
//		access(y),splay(y);
		assert(findrt(y)==x&&fa[x]==y&&!ch[x][1]);
		ch[y][0]=fa[x]=0,update(y);
	}
	inline int query(int x,int y)
	{
		evert(x),access(y),splay(y);
		return mn[y];
	}
	inline void addnode(int k)
	{
		if (u[k]==v[k]) return (void)(a[k]=m+1);
		int x=m+u[k],y=m+v[k];
		if (link(x,y)) cut(x,y);
		else
		{
			a[k]=query(x,y);
			cut(a[k],m+u[a[k]]),cut(a[k],m+v[a[k]]);
		}
		link(x,k),link(y,k);
	}
}
using LCT::addnode;
namespace HJT
{
	int sum[MAXN<<5],ch[MAXN<<5][2],cnt;
	void insert(int& x,int y,int l,int r,int k)
	{
		x=++cnt,sum[x]=sum[y],ch[x][0]=ch[y][0],ch[x][1]=ch[y][1];
		++sum[x];
		if (l==r) return;
		int mid=(l+r)>>1;
		if (k<=mid) insert(ch[x][0],ch[y][0],l,mid,k);
		else insert(ch[x][1],ch[y][1],mid+1,r,k);
	}
	int query(int x,int l,int r,int ql,int qr)
	{
		if (!x) return 0;
		if (ql<=l&&r<=qr) return sum[x];
		if (qr<l||r<ql) return 0;
		int mid=(l+r)>>1;
		return query(ch[x][0],l,mid,ql,qr)+query(ch[x][1],mid+1,r,ql,qr);
	}
}
int rt[MAXN];
using HJT::insert;
using HJT::query;
int main()
{
	n=read(),m=read();
	int q,t;
	q=read(),t=read();
	for (int i=1;i<=m;i++) u[i]=read(),v[i]=read(),addnode(i);
	for (int i=1;i<=m;i++) insert(rt[i],rt[i-1],0,m+1,a[i]);
	int lans=0;
	while (q--)
	{
		int l,r;
		l=read(),r=read();
		if (t) l^=lans,r^=lans;
		printf("%d\n",lans=n-query(rt[r],0,m+1,0,l-1)+query(rt[l-1],0,m+1,0,l-1));
	}
	return 0;
}
代码下载链接: https://pan.quark.cn/s/a4b39357ea24 用户账户控制(UAC)白名单的配置 Windows7环境中 UAC(User Account Control,用户帐户控制)是由微软在Windows Vista版本中推出的一项旨在增强系统安全性的创新技术,该技术强制要求用户在执行可能干扰计算机正常运作的操作或进行更改会波及其他用户设置的变动前,必须提供相应的权限或管理员密码进行验证。通过对这些操作启动前进行授权确认,UAC能够有效阻止恶意软件及间谍软件在未获授权的状态下于计算机内进行安装或实施修改。 自从Vista版本问世以来,微软便开始推行这一全新的安全机制,可视为对系统安全防护的显著提升。尽管UAC确实能够在一定程度上对某些非法程序起到防御作用,但与此同时,这一功能也给众多用户带来了诸多不便。 因此,许多用户开始探寻是否存在类似于白名单的功能,以便将那些值得信赖的程序直接赋予运行权限。事实上,这类功能确实存在,不过微软并未将其作为标准配置提供。 网络上关于此问题的绝大多数建议都是建议禁用UAC,这种说法显然缺乏针对性,因为若用户希望禁用此功能,本就不会提出相关疑问。 通过运用微软官方发布的Microsoft Application Compatibility Toolkit 5.6版本,可以将信任的程序纳入系统白名单范畴。 获取Application Compatibility Toolkit 安装程序成功后会出现三个可执行文件 以管理员身份启动Compatibility Administrator 在Custom DataBases部分创建新的数据库,并添加一个Application Fix(在下方空白处点击右键,选择...
下载代码方式:https://pan.quark.cn/s/a4b39357ea24 DELL服务器的操作系统部署流程包含一系列细致的环节,其适用范围涵盖多种操作系统类型,例如Windows Server与Red Hat Linux等。在启动部署之前,必须确认服务器的光驱设备为DVD驱动器,并且需准备对应的系统安装媒介。下面将详细列出完整的部署步骤: 1. **启动准备**:将随服务器提供的Systems Management Tools and Documentation version 6.0光盘置入服务器光驱,随后设定服务器以光驱作为启动设备。此环节旨在确保服务器在启动阶段能够读取安装光盘内容。 2. **语言设定**:服务器启动后,选定简体中文作为部署语言,并确认接受许可协议条款。 3. **时区选择**:在部署期间,需设定时区为北京、香港、重庆或乌鲁木齐,依据实际地理位置进行适配选择。 4. **系统类型选择**:随后,需选定计划部署的操作系统,支持的版本包括Server 2003 SP2、Server 2003 SP2 64位版本、Windows 2003 SBS SP2、Server 2008、Windows 2008 SBS/EBS x64版本等,以及多种Red Hat和SUSE Linux版本。 5. **RAID设定**:若服务器出厂时已预设RAID配置,则可选择跳过此步骤。若需重新设定RAID,操作时需格外小心,因为这一过程可能引发硬盘数据遗失。 6. **引导分区规划**:设定引导分区的大小,通常C盘建议预留至少20GB的空间,具体容量需根据系统需求进行调整。 7. **网络设定**:网络设定可在系统部署完成后执行,部署期间建议暂时拔除...
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值