2024.7.21模拟赛4

模拟赛

不挂分比挂分打的更少。。。

Qyun%%%

T1 Lights Out on Tree

无脑 O(nq),赛时用树状数组和 dfs 序优化了一下,没想到没有暴力分。

其实菊花和链的都可以打的,下次注意。

我们看数据范围,能操作的只有一个黑点个数,只要涉及白点一定会炸。

所以考虑每一个黑点的贡献(跟前两天单独考虑贡献的好像差不多?)。

观察得,如果它和它的父亲颜色不同就会有贡献。

但是如果对于每一个黑点遍历它的所有白儿子,会炸。

我们反过来考虑,先假设每个点的儿子都是白的,如果有一个黑点的父亲是黑点,那么总的贡献就会减一,否则要加上一。(它也有父亲)

code
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+5;
int n,m;
int a[N],cnt,d[N],fa[N],son[N];
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=2;i<=n;i++)
	{
		int x; scanf("%d",&x);
		fa[i]=x; son[x]++;
	}
	while(m--)
	{
		int c,res=0; scanf("%d",&c);
		for(int i=1;i<=c;i++)
		{
			scanf("%d",&d[i]);
			a[d[i]]=1; res+=son[d[i]];
		}
		for(int i=1;i<=c;i++) if(a[fa[d[i]]]) res--; else res++;
		printf("%d\n",res);
		for(int i=1;i<=c;i++) a[d[i]]=0;
	}
	return 0;
}

T2 Encryption (hard) (medium) (easy)

已经不知道咕了多少天了。。。

注意卡空间!!!

赛时 long long 直接炸!

首先想到单调队列优化 dp,但是有一个取模,直接否掉。

考虑暴力 fi,j 表示前 i 位分成 j 个块的最大价值,记录前缀和,得到状态转移方程:

fi,j=mink=1i1(fk,j1+(sisk) mod p)

然后考虑优化,首先观察性质:

fi,jsi(modp)

所以如果 fx,j>fy,j,那么 fx,j(sx mod p)>fy,j(sy mod p)

因此我们只需要找到最小的 fk,j 就是最优的。不用单调队列维护,直接开一个变量记一下就好了。

注意 5e5×100 开 long long 会炸空间,提前算一下。

code
#include<bits/stdc++.h> 
using namespace std;
const int N = 5e5+5;
#define LL long long
int n,k,p,a[N],s[N];
int f[N][101],pos[101];
int main()
{
	memset(f,0x3f,sizeof(f));
	scanf("%d%d%d",&n,&k,&p);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]),s[i]=(s[i-1]+a[i])%p;
	f[0][0]=0;
	for(int i=1;i<=n;i++)
	{
		for(int h=1;h<=k;h++)
		{
			f[i][h]=f[pos[h-1]][h-1]+(s[i]-s[pos[h-1]]+p)%p;
		}
		for(int j=1;j<=k;j++) if(f[i][j]<f[pos[j]][j]) pos[j]=i;
	}
	printf("%d\n",f[n][k]);
	return 0;
}

T3 ± Increasing Sequence

先随便造一个单调递增串 S,如果这个串就已经满足条件,直接输出。(注意判断这一步,万一真碰上了呢)

然后考虑对这个串进行修改,并且不能改变原有的递增关系。

因此我们考虑对前缀和后缀整体进行操作,这样让前缀减一个值,后缀加一个值,一定不会改变递增关系的。

所以我们遍历所有前缀,如果目前 sum 大于 0,那么碰到一个前缀修改操作和大于 0 的就可以减去差值,直接输出。

其他情况同理,还有后缀的。

code
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+5;
#define LL long long
int n,a[N],s1[N],s2[N];
LL tot,ans[N];
int main()
{
//	freopen("1.in","r",stdin);
//	freopen("o1.out","w",stdout);
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scnaf("%d",&a[i]),s1[i]=s1[i-1]+a[i];
	for(int i=n;i>=1;i--) s2[i]=s2[i+1]+a[i];
	for(int i=1;i<=n;i++) ans[i]=i,tot+=i*a[i];
	if(tot==0)
	{
		printf("Yes\n");
		for(int i=1;i<=n;i++) printf("%lld ",ans[i]);
		return 0;
	}
	if(tot<0)
	{
		for(int i=1;i<=n;i++) if(s1[i]<0) 
		{
			printf("Yes\n");
			for(int j=1;j<=n;j++) j<=i?printf("%lld ",ans[j]+tot):printf("%lld ",ans[j]);
			return 0;
		}	
		for(int i=n;i>=1;i--) if(s2[i]>0)
		{
			printf("Yes\n");
			for(int j=1;j<=n;j++) j>=i?printf("%lld ",ans[j]-tot):printf("%lld ",ans[j]);
			return 0;
		}
	}
	else
	{
		for(int i=1;i<=n;i++) if(s1[i]>0) 
		{
			printf("Yes\n");
			for(int j=1;j<=n;j++) j<=i?printf("%lld ",ans[j]-tot):printf("%lld ",ans[j]);
			return 0;
		}
		for(int i=n;i>=1;i--) if(s2[i]<0)
		{
			printf("Yes\n");
			for(int j=1;j<=n;j++) j>=i?printf("%lld ",ans[j]+tot):printf("%lld ",ans[j]);
			return 0;
		}
	}
	printf("No\n");
}

T4 捉迷藏

posted @   ppllxx_9G  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示