首页 > 其他分享 >2024.03 别急记录

2024.03 别急记录

时间:2024-03-01 11:26:02浏览次数:18  
标签:lenmax 2024.03 别急 记录 int fa vector ancmin ancmax

1. IOI2018 - 狼人 / werewolf [省选/NOI-]

题意简述:多次询问求是否存在一条 \(s\to t\) 的路径 \(a_1,a_2,...,a_k\) 和路径上一个点 \(a_i\) 使 \(a_1,...,a_i\in[L,n]\) 且 \(a_i,...,a_k\in[1,R]\)。

首先求出两棵 kruskal 重构树:

  • 第一棵树边权值设为 \(\min(u,v)\),由大到小插入每一条边,树上点权设为子树内点权 \(\min\),则可通过倍增跳树的方式求得每个点经过 \(\geq L\) 的点能到达的点集合(一个子树内所有叶子);
  • 第二棵树边权值设为 \(\max(u,v)\),由小到大插入每一条边,树上点权设为子树内点权 \(\max\)。

因为一个子树内所有叶子是 dfn 序上一段连续区间,dfn 序又是一个排列,问题转化为了两个排列 \(a,b\),求 \(a_{[l,r]},b_{[p,q]}\) 是否有交。

设 \(a^{-1}_i\) 表示 \(i\) 在 \(a\) 中的出现位置,若有交则等价于存在 \(x\in[p,q]\) 使 \(a^{-1}_{b_x}\in{[l,r]}\)。设排列 \(c_i=a^{-1}_{b_i}\),则等价于 \(c_{[p,q]}\) 中存在值域 \(\in [l,r]\) 的数。

考虑使用主席树维护 \(c\)。每次询问查询 \(c_{[1,q]},c_{[1,p-1]}\) 中值域 \(\in[l,r]\) 的数的个数。若二者不等则答案为 \(1\),否则为 \(0\)。

点击查看代码
const int N = 4e5 + 10;
int n, m, Q, fa[N], anti[N], c[N];
int ancmin[N][20], lenmin[N], ancmax[N][20], lenmax[N];
int dfnmin[N], dfnmax[N], mnmin[N], mxmin[N], mnmax[N], mxmax[N];
pair<int, int> emin[N], emax[N];
vector<int> gmin[N], gmax[N];

bool cmpmin(pair<int, int> x, pair<int, int> y){
	return min(x.first, x.second) > min(y.first, y.second);
}
bool cmpmax(pair<int, int> x, pair<int, int> y){
	return max(x.first, x.second) < max(y.first, y.second);
}
int gf(int x){
	return x == fa[x] ? x : fa[x] = gf(fa[x]);
}
void dfsmin(int x){
	if(x <= n){
		++ *dfnmin;
		dfnmin[*dfnmin] = x;
		mnmin[x] = mxmin[x] = *dfnmin;
		return;
	}
	mnmin[x] = 1e9;
	for(int i : gmin[x]){
		dfsmin(i);
		mnmin[x] = min(mnmin[i], mnmin[x]);
		mxmin[x] = max(mxmin[i], mxmin[x]);
	}
}
void dfsmax(int x){
	if(x <= n){
		++ *dfnmax;
		dfnmax[*dfnmax] = x;
		mnmax[x] = mxmax[x] = *dfnmax;
		return;
	}
	mnmax[x] = 1e9;
	for(int i : gmax[x]){
		dfsmax(i);
		mnmax[x] = min(mnmax[i], mnmax[x]);
		mxmax[x] = max(mxmax[i], mxmax[x]);
	}
}
int jmpmin(int x, int val){
	for(int i = 19; i >= 0; -- i){
		if(lenmin[ancmin[x][i]] >= val){
			x = ancmin[x][i];
		}
	}
	return x;
}
int jmpmax(int x, int val){
	for(int i = 19; i >= 0; -- i){
		if(lenmax[ancmax[x][i]] <= val){
			x = ancmax[x][i];
		}
	}
	return x;
}

int rt[N], t[N*40], cnt, ls[N*40], rs[N*40];
int add(int p, int l, int r, int x, int v){
	++ cnt;
	t[cnt] = t[p];
	ls[cnt] = ls[p];
	rs[cnt] = rs[p];
	p = cnt;
	if(l == r){
		t[p] += v;
	} else {
		int mid = l + r >> 1;
		if(x <= mid){
			ls[p] = add(ls[p], l, mid, x, v);
		} else {
			rs[p] = add(rs[p], mid+1, r, x, v);
		}
		t[p] = t[ls[p]] + t[rs[p]];
	}
	return p;
}
int qry(int p, int l, int r, int ql, int qr){
	if(!p || qr < l || r < ql){
		return 0;
	} else if(ql <= l && r <= qr){
		return t[p];
	} else {
		int mid = l + r >> 1;
		return qry(ls[p], l, mid, ql, qr) 
			   + qry(rs[p], mid+1, r, ql, qr);
	}
}

vector<int> check_validity(
			int N, 
			vector<int> X, 
			vector<int> Y, 
			vector<int> S, 
			vector<int> E, 
			vector<int> L,
        	vector<int> R) {
	vector<int> ans;
	n = N;
	m = X.size();
	Q = S.size();
	for(int i = 1; i <= m; ++ i){
		emin[i].first = X[i-1];
		emin[i].second = Y[i-1];
		++ emin[i].first;
		++ emin[i].second;
		emax[i] = emin[i];
	}
	sort(emin + 1, emin + m + 1, cmpmin);
	iota(fa + 1, fa + n + n + 1, 1);
	iota(lenmin + 1, lenmin + n + 1, 1);
	int cnt = n;
	for(int i = 1; i <= m; ++ i){
		int x = gf(emin[i].first), y = gf(emin[i].second);
		if(x != y){
			fa[x] = fa[y] = ++ cnt;
			gmin[cnt].push_back(x);
			gmin[cnt].push_back(y);
			ancmin[x][0] = ancmin[y][0] = cnt;
			lenmin[cnt] = min(lenmin[x], lenmin[y]);
		}
	}
	dfsmin(cnt);
	for(int i = cnt; i >= 1; -- i){
		for(int j = 1; j < 20; ++ j){
			ancmin[i][j] = ancmin[ancmin[i][j-1]][j-1];
		}
	}
	sort(emax + 1, emax + m + 1, cmpmax); 
	iota(fa + 1, fa + n + n + 1, 1);
	memset(lenmax, 0x3f, sizeof(lenmax));
	iota(lenmax + 1, lenmax + n + 1, 1);
	cnt = n;
	for(int i = 1; i <= m; ++ i){
		int x = gf(emax[i].first), y = gf(emax[i].second);
		if(x != y){
			fa[x] = fa[y] = ++ cnt;
			gmax[cnt].push_back(x);
			gmax[cnt].push_back(y);
			ancmax[x][0] = ancmax[y][0] = cnt;
			lenmax[cnt] = max(lenmax[x], lenmax[y]);
		}
	}
	dfsmax(cnt);
	for(int i = cnt; i >= 1; -- i){
		for(int j = 1; j < 20; ++ j){
			ancmax[i][j] = ancmax[ancmax[i][j-1]][j-1];
		}
	}
	for(int i = 1; i <= n; ++ i){
		anti[dfnmin[i]] = i;
	}
	for(int i = 1; i <= n; ++ i){
		c[i] = anti[dfnmax[i]];
		rt[i] = add(rt[i-1], 1, n, c[i], 1);
	}
	for(int i = 0; i < Q; ++ i){
		int st = S[i], ed = E[i], le = L[i], ri = R[i];
		++ st;
		++ ed;
		++ le;
		++ ri;
		int x = jmpmin(st, le), y = jmpmax(ed, ri);
		int l = mnmin[x], r = mxmin[x], p = mnmax[y], q = mxmax[y];
		int v = qry(rt[q], 1, n, l, r) - qry(rt[p-1], 1, n, l, r);
		if(v){
			ans.push_back(1);
		} else {
			ans.push_back(0);
		}
	}
	return ans;
}

标签:lenmax,2024.03,别急,记录,int,fa,vector,ancmin,ancmax
From: https://www.cnblogs.com/KiharaTouma/p/18046559/2024-03

相关文章

  • [CS61A-Fall-2020]学习记录四 Lecture4中有意思的点
    首先,本文不是总结归纳,只是记录一些有趣的知识点罢了assert课堂中在讲授函数,如frommathimportpidefarea_circle(r):returnr*r*pi但老师提出,当r为-10时,函数不会报错,于是引入assert来检测参数frommathimportpidefarea_circle(r):#参数应为正数......
  • 模板记录
    RMQ求Lca怕考场被卡,所以临省选重新复习一下。有个性质:若\(u,v\)不成祖先和儿子关系,则\(u,v\)的\(lca\)的\(dfs\)序一定不在\(dfn_u\)到\(dfn_v\)之间,所以我们只用找到\(dfn_u\)到\(dfn_v\)之间深度最小点\(d\)的就行了,\(d\)的父亲显然是\(u,v\)的\(lca\)......
  • 记录一次修复蓝牙故障经过(硬件管理器:“目前,这个硬件设备没有连接到计算机。(代码 45)
    记录一次修复蓝牙故障经过(硬件管理器:“目前,这个硬件设备没有连接到计算机。(代码45)”)来源https://zhuanlan.zhihu.com/p/491185819 2022年3月中旬重装win10系统,下旬欲使用蓝牙时发现没有安装驱动,便从Acer官网下载驱动进行安装,失败,遂尝试驱动人生、驱动精灵、booster9安......
  • 记账本开发记录六
    添加收入或支出布局文件<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent......
  • 记账本开发记录八
    实现第三个功能,查看账单记录。和往常相同,首先制作页面布局  <?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layo......
  • vue中draggable使用记录
    NPM或yarn安装方式yarnaddvuedraggablenpmi-SvuedraggableUMD浏览器直接引用JS方式<scriptsrc="https://www.itxst.com/package/vue/vue.min.js"></script><scriptsrc="https://www.itxst.com/package/sortable/Sortable.min.js"></scri......
  • 好用的网站记录
    1.DataV一个基于Vue的数据可视化组件库,提供用于提升页面视觉效果的SVG边框和装饰、常用的图表如折线图等和飞线图/轮播表等其他组件 在线观看地址:DataV(jiaminghi.com)github地址:GitHub-lin-xin/vue-manage-system:Vue3、ElementPlus、typescript后台管理系统  2......
  • ssts-hospital-web-master项目实战记录三十:项目迁移-Hook实现(useSystemService)
    记录时间:2024-02-29一、useSystemService模块实现service/system-service/useTerminalService.tsimporthydatefrom'@/utils/date-format'import{LogInfo}from'@/framework/utils/log-local'import{Device}from'@/types/device'impor......
  • NVME FPGA IP测试记录
    这里涉及商业IP的部分文字资料,如有侵权,请联系删除。当前只说明基础测试,更多测试待后续更新。NVMEHOSTIPIP特性范例截图ZCU106测试使用ZCU106HPC0接口+FMCDriveNVME接口子卡,NVME使用三星980测试日志EnteringMainStartinginitialization...Expecting1dr......
  • 小白的学习记录——微服务技术栈第一天:认识微服务
    今天开始学习微服务首先从三部分开始简单的认识微服务:服务器架构的演变微服务技术对比SpringCloud服务器架构的演变单体(应用)架构:这是最初的服务器架构形式,所有的功能都被打包成一个单独的应用程序,运行在一个或多个服务器上。优点:架构简单部署成本低缺点:耦......