首页 > 其他分享 >2024.8.8模拟赛16

2024.8.8模拟赛16

时间:2024-09-05 10:49:27浏览次数:5  
标签:遍历 16 2024.8 bl 轻链 int 串中 include 模拟

模拟赛

重拾题解(刚刚写过一版忘保存了)

T1

其实就是个最长公共子序列的变形。把一样的数才匹配换成有倍数关系就匹配。

最长公共子序列:一般转化为最长上升子序列,即在一个串中的数 \(a\),找到它在另一个串中的位置 \(j\),从 \(1 \dots j-1\) 转移即可,取最大值可用树状数组维护前缀最大值。

本题需要找到在第一个串中每个数的倍数在第二个串中的位置,由于调和级数,只会有 \(log\) 个,然后转移时从后往前遍历,防止本层干扰。

code
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+5;
int n,a[N],b[N],pos[N],f[N],c[N],ans;
vector<int> v[N];
inline bool cmp(int &x,int &y) {return x>y;}
inline void add(int x,int v)
{
	for(;x<=n;x+=(x&-x)) c[x]=max(c[x],v);
}
inline int que(int x)
{
	int res=0;
	for(;x;x-=(x&-x)) res=max(c[x],res);
	return res;
}
int main()
{
	// freopen("in.in","r",stdin);
	// freopen("out.out","w",stdout);
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	for(int i=1;i<=n;i++) scanf("%d",&b[i]),pos[b[i]]=i;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j*a[i]<=n;j++)
			v[i].push_back(pos[j*a[i]]);
		sort(v[i].begin(),v[i].end(),cmp);
		for(int j:v[i])
		{
			f[j]=max(f[j],que(j-1)+1);
			ans=max(ans,f[j]);
			add(j,f[j]);
		}
	}
	printf("%d\n",ans);
	return 0;
}

T2 大爷的字符串题

转化题意,就是查询区间众数

然后开始莫队 \(\mathbb{MQ}\)!

一种直接用回滚,另一种可以维护每一个数在区间中的出现次数,然后再维护出现次数的出现次数

注意离散化。

其实挺板的。

code
#include<cstdio>
#include<math.h>
#include<algorithm>
#include<unordered_map>
using namespace std;
#define mx(x,y) (x>y?x:y)
#define LL long long
const int N = 2e5+5;
int n,m,a[N],bl[N],tot;
struct Q {int l,r,id;} q[N];
int cnt[N],Cnt[N],ans[N],now;
unordered_map<int,int> mp;
inline bool cmp(Q &x,Q &y)
{
	return bl[x.l]==bl[y.l]?((bl[x.l]&1)?(x.r<y.r):(x.r>y.r)):bl[x.l]<bl[y.l];
}
inline void add(int x)
{
	Cnt[cnt[x]]--;
	cnt[x]++;
	Cnt[cnt[x]]++;
	now=mx(now,cnt[x]);
}
inline void del(int x)
{
	Cnt[cnt[x]]--;
	if(now==cnt[x]&&Cnt[cnt[x]]==0) now--;
	cnt[x]--;
	Cnt[cnt[x]]++;
}
void mq()
{
	for(int i=1,l=1,r=0;i<=m;i++)
	{
		int tl=q[i].l,tr=q[i].r;
		while(l<tl) del(a[l++]);
		while(l>tl) add(a[--l]);
		while(r>tr) del(a[r--]);
		while(r<tr) add(a[++r]);
		ans[q[i].id]=-now;
	}
}
int main()
{
	// freopen("in.in","r",stdin);
	// freopen("out.out","w",stdout);
	scanf("%d%d",&n,&m); int len=n/sqrt(m);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]),bl[i]=(i-1)/len+1;
		if(!mp[a[i]]) mp[a[i]]=++tot;
		a[i]=mp[a[i]];
	}
	for(int i=1;i<=m;i++) scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i;
	sort(q+1,q+1+m,cmp);
	mq();
	for(int i=1;i<=m;i++) printf("%d\n",ans[i]);
	return 0;
}

T3 Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths

启发式合并。

注意理解题意,是每棵子树内最长的合法链

因为只有 \(22\) 位,所以考虑状压,一个串是否是回文串,我们只在乎其中出现次数为奇数的字符个数,所以用 \(1\) 表示出现奇数次,\(0\) 表示出现偶数次。

至于串的长度可以直接用深度差分得到。

依旧运用差分的思想,我们预处理根到每个点路径异或和,然后就可以从中截取一段路径。(以下状态都表示到根的异或和)

其实我们最终就是要找到某两个点之间的路径异或和为 \(0\) 或者只有一个 \(1\),那么对于某个状态 \(d[u]\),我们想找到的就是某个点的状态为 \(d[u]\) 或 \(d[u]^(1<<i)\),这样两点间的路径就是合法的。

现在我们有了判断合法的方法,考虑如何对每一棵子树进行求解。如果直接遍历一定是 \(n^2\) 的,所以我们考虑用轻重链划分的方法进行启发式合并

我们选择整体维护重链的信息(全维护开不下),然后暴力遍历轻链,由于每次合并都会使需要遍历的轻链大小至少翻倍,所以复杂度 \(O(n\log n)\)。

然后每次遍历一棵轻链,在已经合并的子树里找有没有能匹配合法的。然后注意我们维护的只是重儿子所在子树,所以对于那些轻儿子的信息要在处理完清空。

code
#include<bits/stdc++.h>
using namespace std;
#define mx(x,y) (x>y?x:y)
const int N = 1e6+5;
int n,ans[N];
int head[N],tot;
struct E {int u,v,w;} e[N<<1];
inline void add(int u,int v,int w) {e[++tot]={head[u],v,w}; head[u]=tot;}
int sz[N],son[N],dep[N],dfn[N],cnt,L[N],R[N],book[N*10],d[N];

inline void dfs(int u,int f)
{
	sz[u]=1; dep[u]=dep[f]+1; L[u]=++cnt; dfn[cnt]=u;
	for(int i=head[u];i;i=e[i].u)
	{
		int v=e[i].v; d[v]=d[u]^e[i].w;
		dfs(v,u); sz[u]+=sz[v]; 
		if(sz[son[u]]<sz[v]) son[u]=v;
	}
	R[u]=cnt;
}
inline void dfs2(int u,bool keep)
{
	for(int i=head[u];i;i=e[i].u)
	{
		int v=e[i].v; if(v==son[u]) continue;
		dfs2(v,0); ans[u]=mx(ans[u],ans[v]);
	}
	if(son[u]) dfs2(son[u],1),ans[u]=mx(ans[u],ans[son[u]]);
	if(book[d[u]]) ans[u]=mx(ans[u],book[d[u]]-dep[u]);
	for(int i=0;i<22;i++) if(book[d[u]^(1<<i)]) ans[u]=mx(ans[u],book[d[u]^(1<<i)]-dep[u]);
	book[d[u]]=mx(book[d[u]],dep[u]);
	for(int i=head[u];i;i=e[i].u)
	{
		int v=e[i].v; if(v==son[u]) continue;
		for(int j=L[v];j<=R[v];j++)
		{
			int x=dfn[j];
			if(book[d[x]]) ans[u]=mx(ans[u],book[d[x]]+dep[x]-(dep[u]<<1));
			for(int k=0;k<22;k++) if(book[d[x]^(1<<k)]) ans[u]=mx(ans[u],book[d[x]^(1<<k)]+dep[x]-(dep[u]<<1));
		}
		for(int j=L[v];j<=R[v];j++)
		{
			int x=dfn[j];
			book[d[x]]=mx(book[d[x]],dep[x]);
		}
	}
	if(!keep) for(int i=L[u];i<=R[u];i++) book[d[dfn[i]]]=0;
}

int main()
{
	// freopen("in.in","r",stdin);
	// freopen("out.out","w",stdout);
	scanf("%d",&n);
	for(int i=2;i<=n;i++)
	{
		int x; char c; scanf("%d %c",&x,&c);
		add(x,i,1<<(c-'a'));
	}
	dfs(1,1); dfs2(1,1);
	for(int i=1;i<=n;i++) printf("%d ",ans[i]);
	return 0;
}

标签:遍历,16,2024.8,bl,轻链,int,串中,include,模拟
From: https://www.cnblogs.com/ppllxx-9G/p/18350055

相关文章

  • 深入解析如何利用1688 API接口获取详尽商品信息
    在电子商务的蓬勃发展中,数据的重要性日益凸显。对于商家而言,能够实时获取并分析商品数据,是提升市场竞争力的关键。1688作为阿里巴巴集团旗下的知名B2B平台,提供了丰富的API接口,使得商家能够轻松获取商品详情。本文将为您全面解析如何通过1688商品详情API接口获取所需数据。一、......
  • 深入解析如何利用1688 API接口获取详尽商品信息
    在电子商务的蓬勃发展中,数据的重要性日益凸显。对于商家而言,能够实时获取并分析商品数据,是提升市场竞争力的关键。1688作为阿里巴巴集团旗下的知名B2B平台,提供了丰富的API接口,使得商家能够轻松获取商品详情。本文将为您全面解析如何通过1688商品详情API接口获取所需数据。一、168......
  • Day85 APP攻防-资产收集篇&反证书检验&XP框架&反代理VPN&数据转发&反模拟器
    知识点1、APP资产-抓包突破&反模拟器2、APP资产-抓包突破&反证书检验3、APP资产-抓包突破&反代理VPN没有限制过滤的抓包问题:1、抓不到-工具证书没配置好2、抓不到-app走的不是http/s不走http/s协议的数据包抓不到可以用封包抓有限制过滤的抓包问题:3、抓不到-......
  • 6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)
    目录一.堆(Heap)的基本介绍二.堆的常用操作(以小根堆为例)三.实现代码3.1堆结构定义3.2向下调整算法*3.3初始化堆*3.4销毁堆3.4向上调整算法* 3.5插入数据3.6删除数据3.7返回堆顶数据四.下篇内容1.堆排序2.TopK问题一.堆(Heap)的基本介绍    ......
  • 深入了解链表 list 之的模拟实现 list (C++)
    1.基本框架关于链表我们知道其是一个双向循环结构,并且由许多节点组成,各个节点之间内存空间不一定连续,每个节点均有前驱指针与后继指针,下面我们使用类模版来实现一个适用于存储大部分数据类型的链表,由下面代码我们可以看到一些基础框架与很简单的函数size返回长度与empty判断......
  • Charles - 夜神模拟器证书安装App抓包-charles监控手机出现unknown 已解决
    1.Openssl安装http://slproweb.com/products/Win32OpenSSL.htmlexe下载安装后进行配置 新建系统变量OPENSSL_HOME,变量值设为(绝对路径)软件安装目录下的bin直接浏览 编辑用户变量path,新建%OPENSSL_HOME%,最后点击确定 查看openssl版本,输入命令:opensslversion  2......
  • 2024.8
    1.ARC183DKeepPerfectlyMatched思考了一会后,发现答案是存在一个上界的:以重心\(r\)定根,一条边至多经过\(sz_i\)次。而这个东西一出来,就知道一定是能顶到的了,因为太典了。我们考虑,当且仅当,每次删除的两个叶子,都属于\(r\)的两颗不同子树,符合要求。而一次删除,怎么样才能让......
  • CF1316F sol
    简化题意传送门定义一个长度为\(n\)的权值\(val(p)=\sum\limits_{i=1}^{n-1}p^{'}_ip^{'}_{i+1}\),其中\(p^{'}\)为\(p\)排序后的序列。特殊的,如果\(n\le1\),\(val(p)=\text{0}\)现在给定长度为\(n\)一个序列\(a\),\(a\)的所有子序列\(a^{'}\)的\(val(a^{'})\)的\(\......
  • C语言学习笔记 Day16(文件管理--下)
    Day16 内容梳理:C语言学习笔记Day14(文件管理--上)-CSDN博客C语言学习笔记Day15(文件管理--中)-CSDN博客目录Chapter10 文件操作10.5文件状态10.6文件的随机读写fseek()、rewind()(1)fseek():移动光标并开始读写(2)rewind():将光标重置回文件开头10.7文件的删除remove(......
  • 使用Python模拟TCP/IP协议栈
    1.代码如下importrandomclassApplicationLayer:defsend_data(self,data):print(f"ApplicationLayer:Sendingdata:{data}")returndatadefreceive_data(self,data):print(f"ApplicationLayer:Receiveddata......