首页 > 其他分享 >2024.7.25模拟赛7

2024.7.25模拟赛7

时间:2024-07-30 09:06:04浏览次数:10  
标签:25 return 2024.7 int res mid fa sz 模拟

模拟赛

疯狂补题解/改题中。。。

T1 [Permutations & Primes] (未找到)

构造一个 \(1-n\) 的序列,使所有区间中 \(mex\) 为质数的最多。

感觉题不是很好。结论是:\(1\) 放中间,\(2,3\) 放两边。

打标找规律,感性证明也挺显然的。

no code

T2 Spread of Information

首先看道典题:消防局的设立

题很水,但是思路一样,半径为 \(k\) 的最小覆盖问题就是跳 \(k\) 级祖先。

采用贪心的策略,每次找到没有被覆盖的最深的点,向上跳 \(k\) 级祖先,使当前没被覆盖的这个点刚好被覆盖。

但是这道题暴跳肯定不行,因为跳跃过程中要更新最小距离,倍增也不太好搞。

所以我们稍微变一下思路,还是跳祖先,跳到祖先直接 dfs 把能覆盖的点都标记。这样被标记的点一定不会再被跳。

虽然看着很暴力,但真的很快,而且卡不掉?

code
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+5;
int n,k,a[N],dep[N],fa[N];
int head[N],tot;
struct E {int u,v;} e[N<<1];
inline void add(int u,int v) {e[++tot]={head[u],v}; head[u]=tot;}
inline int qr()
{
	char ch=getchar();int x=0,f=1;
	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
	for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<3)+(x<<1)+(ch^48);
	return x*f;
}
inline void dfs(int u,int f)
{
	dep[u]=dep[f]+1; a[u]=u; fa[u]=f;
	for(int i=head[u];i;i=e[i].u)
	{
		int v=e[i].v;
		if(v==f) continue;
		dfs(v,u);
	}
}
inline bool cmp(int x,int y) {return dep[x]>dep[y];}
bool vs[N];
inline void fg(int u,int f,int d,int mid)
{
	if(d>mid) return;
	vs[u]=1;
	for(int i=head[u];i;i=e[i].u)
	{
		int v=e[i].v;
		if(v==f) continue;
		fg(v,u,d+1,mid);
	}
}
inline bool check(int mid)
{
	int res=0;
	for(int i=1;i<=n;i++) vs[i]=0;
	for(int i=1;i<=n;i++) if(!vs[a[i]])
	{
		int u=a[i],jp=mid;
		while(fa[u]&&jp) u=fa[u],jp--;
		fg(u,0,0,mid);
		res++;
		if(res>k) return 0;		
	}
	return 1;
}
int main()
{
	n=qr(); k=qr();
	for(int i=1;i<n;i++)
	{
		int x=qr(),y=qr();
		add(x,y); add(y,x); 
	}
	dfs(1,0);
	sort(a+1,a+1+n,cmp);
	int l=1,r=dep[a[1]],ans=r;
	while(l<=r)
	{
		int mid=l+r>>1;
		if(check(mid)) ans=mid,r=mid-1;
		else l=mid+1;
	}
	printf("%d\n",ans);
	return 0;
}

还可以倍增优化一下暴跳,好像变慢了。

倍增code
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+5;
int n,k,a[N],dep[N],fa[20][N],lg;
int head[N],tot;
struct E {int u,v;} e[N<<1];
inline void add(int u,int v) {e[++tot]={head[u],v}; head[u]=tot;}
inline int qr()
{
	char ch=getchar();int x=0,f=1;
	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
	for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<3)+(x<<1)+(ch^48);
	return x*f;
}
inline void dfs(int u,int f)
{
	dep[u]=dep[f]+1; a[u]=u; fa[0][u]=f;
	for(int i=1;i<=lg;i++) fa[i][u]=fa[i-1][fa[i-1][u]];
	for(int i=head[u];i;i=e[i].u)
	{
		int v=e[i].v;
		if(v==f) continue;
		dfs(v,u);
	}
}
inline bool cmp(int x,int y) {return dep[x]>dep[y];}
bool vs[N];
inline void fg(int u,int f,int d,int mid)
{
	if(d>mid) return;
	vs[u]=1;
	for(int i=head[u];i;i=e[i].u)
	{
		int v=e[i].v;
		if(v==f) continue;
		fg(v,u,d+1,mid);
	}
}
inline bool check(int mid)
{
	int res=0;
	for(int i=1;i<=n;i++) vs[i]=0;
	for(int i=1;i<=n;i++) if(!vs[a[i]])
	{
		int u=a[i];
		for(int j=lg;j>=0;j--) if(fa[j][u]&&dep[fa[j][u]]>=dep[a[i]]-mid) u=fa[j][u];
		fg(u,0,0,mid);
		res++;
		if(res>k) return 0;		
	}
	return 1;
}
int main()
{
//	freopen("in.in","r",stdin);
	n=qr(); k=qr(); lg=__lg(n);
	for(int i=1;i<n;i++)
	{
		int x=qr(),y=qr();
		add(x,y); add(y,x); 
	}
	dfs(1,0);
	sort(a+1,a+1+n,cmp);
	int l=1,r=dep[a[1]],ans=r;
	while(l<=r)
	{
		int mid=l+r>>1;
		if(check(mid)) ans=mid,r=mid-1;
		else l=mid+1;
	}
	printf("%d\n",ans);
	return 0;
}

T3 Ball Collector

一开始想二分图,树上遍历同时跑匈牙利。后来 GGrun 证明可以,HACK 之后 \({mathbb{MLE}}\)。

其实思路还是类似的,将同一个节点的两个颜色连边。

观察得性质,每选一个节点的颜色就相当于选一条边,如果边数大于颜色点数,那么一定可以选中所有颜色。否则有多少条边就能选多少种颜色。

因此对于我们以颜色为点建的图中,答案就是 \(\min(点数,边数)\) 。

然后考虑实时维护这个图。用到新科技:可撤销并查集

其实原理很简单,就是在树上递归到一个点时记录这个状态,回溯时把它回归这个状态。

查询时不能路径压缩,合并时需要按秩合并(类似启发式合并,浅的合并到深的里,本题 \(sz\) 越大越深)。

好像挺简单的?

code
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+5;
int n,ans[N],res,a[N],b[N],fa[N],sz[N],ed[N];
int head[N],tot;
struct E {int u,v;} e[N<<1];
inline void add(int u,int v) {e[++tot]={head[u],v}; head[u]=tot;}
int find(int x) {return fa[x]==x?x:find(fa[x]);}
struct A {int x,fa,sz,e;} g[N];
void merge(int u,int v,stack<A> &st,int &ans)
{
	u=find(u); v=find(v);
	st.push(A{u,fa[u],sz[u],ed[u]});
	st.push(A{v,fa[v],sz[v],ed[v]});
	if(u==v)
	{
		ed[u]++;
		if(ed[u]==sz[u]) res++;
		return;
	}
	if(sz[u]<sz[v]) swap(u,v);
	ans-=min(sz[u],ed[u]); res-=min(sz[v],ed[v]);
	fa[v]=u; sz[u]+=sz[v]; ed[u]+=ed[v]+1;
	ans+=min(sz[u],ed[u]);
}
void dfs(int u,int f)
{
	stack<A> st; int tmp=res;
	merge(a[u],b[u],st,res);
	ans[u]=res;
	for(int i=head[u];i;i=e[i].u)
	{
		int v=e[i].v;
		if(v==f) continue;
		dfs(v,u);
	}
	while(!st.empty())
	{
		A pre=st.top(); st.pop();
		fa[pre.x]=pre.fa;
		sz[pre.x]=pre.sz;
		ed[pre.x]=pre.e;
	}
	res=tmp;
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]);
	for(int i=1;i<n;i++)
	{
		int x,y; scanf("%d%d",&x,&y);
		add(x,y); add(y,x);
	}
	for(int i=1;i<=n;i++) fa[i]=i,sz[i]=1,ed[i]=0;
	dfs(1,0);
	for(int i=2;i<=n;i++) printf("%d ",ans[i]);
	return 0;
}

T4 Joker

先挂张图,咕咕咕。。。

标签:25,return,2024.7,int,res,mid,fa,sz,模拟
From: https://www.cnblogs.com/ppllxx-9G/p/18326574

相关文章

  • 昇思25天学习打卡营第19天|ResNet50 图像分类案例:数据集、训练与预测可视化
    目录环境配置数据集加载数据集可视化BuildingBlockBottleneck构建ResNet50网络模型训练与评估可视化模型预测环境配置        首先指出实验环境预装的mindspore版本以及更换版本的方法。然后,它卸载了已安装的mindspore并重新安装指定的2.3.0rc1版......
  • [OI] 模拟退火
    模拟退火是一种适合求样本点较大的多峰函数极值的方法.模拟退火有几个参数:初始温度(\(T_{0}\)),终止温度(\(T_{e}\))和降温参数\(d\),具体地,模拟退火是让每次的当前温度\(T\)变为\(d\timesT\),直到终止,因此\(T_{e}\)应为一个很接近\(0\)的正数,\(d\)应该为一个很接近\(1\)的......
  • 有什么方法可以将模拟对象伪装成 Qt 方法参数中可接受的 PyQt 对象吗?
    这是MRE。您需要pytest安装...事实上pytest-qt不会造成任何伤害。importsys,pytestfromPyQt5importQtWidgetsfromunittestimportmockclassMyLineEdit(QtWidgets.QLineEdit):def__init__(self,parent):super().__init__(paren......
  • mysql的MHA以及故障模拟
    目录MHA概念MHA的组件MHA的特点实验:搭建完成MHA的架构实验:主备切换实验结果实验:故障切换实验:故障恢复MHA概念MHA:高可用模式下的故障切换,基于主从复制。它解决的是单点故障和主从复制不能切换的问题。它至少需要3台。故障切换过程0-30秒。它能根据VIP地址所在的主机......
  • 「模拟赛」暑期集训CSP提高模拟10(7.28)
    \(145pts,Rank10\),众数分。数学专题模拟赛%%%总结写前面:1.线性递推式复杂度过大考虑矩阵快速幂优化;2.T1长时间切不了就先跳,先把所有题看一遍,拿分为主。赛时记录正常开T1,期望数学题,大概读懂了,手模下小样例,模了一遍又一遍,“我并不认为样例是对的”,跳了(很正确的决定)。......
  • 2024.7.29 test
    A给出\(n,m\),你要求对于所有长度为\(n\)的非负整数序列\(A,B\)中,满足\(\sumA_i=\sumB_i=m\),求\((\sum|A_i-B_i|)^2\)的总和。\(n\le500,m\le10^5\)。首先我们发现\(\sum(A_i-B_i)=0\),所以\(\sum|A_i-B_i|=2\sum_{A_i<B_i}B_i-A_i\)。我们把序列分为两部分,一......
  • 暑假集训csp提高模拟11
    赛时rank9,T1100,T2100,T30,T40update:赛后T1被hack了,成了99,死因没有记忆化挂成了rank10我又要挂分了。T3暴力挂了?话说jjdw和k8啥时候回来。T1Fate签到题,最短路板子。考虑一个点\(a\),其最短路前驱节点为\(b\),前驱结点组成的集合为\(B\),其次短路的前驱节点为......
  • 暑假集训CSP提高模拟11
    A.Fate求次短路方案数.这题有点小水了,好像之前做过.具体的方案显然是DP,考虑枚举当前每一个路径长度,假如比最短路更优则覆盖最短路,之前的最短路用来覆盖次短路.否则如果比次短路更优,则直接覆盖次短路.方案数的话考虑一样的方法维护,只是在遇到相等的路径长时使方案数加一即可.......
  • 暑假集训CSP提高模拟11
    暑假集训CSP提高模拟11组题人:@KafuuChinocpp\(T1\)P152.Fate\(24pts\)强化版:HDU1688Sightseeing设\(dis_{i,0/1}\)表示从\(s\)到\(i\)的最短路/次短路长度,\(f_{i,0/1}\)表示从\(s\)到\(i\)的最短路/次短路条数。\(dijkstra\)过程中按照路径长度与......
  • 『模拟赛』暑假集训CSP提高模拟11
    Rank昨天积攒的rp生效了!A.Fate签到题。次短路计数,感觉做过类似的,不过这里次短路定义为最短路长度+1,赛时把自环想成环了,原谅我犯唐。还是用dijkstra,我们这次开两个dis数组存最短路和次短路长度,然后两个cnt数组存二者的个数,稍微想想就能想到一共的四种可能:更新后......