Atcoder Regular Contest 166

news2024/9/23 13:23:46

只打了半场。

A. Replace C or Swap AB

首先如果存在某个 \(i\),使得 \(Y_i\)C\(X_i\) 不是,那么显然是不合法的,可以直接判掉。
那么除去上述情况 \(Y\) 中为字符 C 的位置 \(X\) 也只能是 C。它们把字符串分成了若干段,可以把每一段分开单独考虑。
对于只含 A/B 的一段 \(Y\),我们可以根据个数得出 \(X\) 在这段中应该把多少 C 替换成 A,剩下的换成 B
发现题意只能从 AB 换成 BA,等价于把某个 A 向后移一个位置。
那我们希望我们放置的 A 尽量靠前,使最后能成功匹配的概率最大。因此根据已知数量,贪心地把靠前的 C 都替换成 A
判断当前 \(X\) 中是否每个对应的 A 所在位置都不大于它在 \(Y\) 中的目标位置即可。

Code
const int N=2e5+5;
int T,n;
char s[N],t[N];
vector<int> x,y;
bool solve()
{
	n=read();
	scanf("%s%s",s+1,t+1);
	int lst=0,cnt=0;
	s[n+1]=t[n+1]='C'; 
	for(int i=1;i<=n+1;i++)
	{
		if(t[i]=='C')
		{
			if(s[i]!='C') return 0;
			int cnta=0,cntb=0;
			int sa=0,sb=0;
			x.clear(),y.clear();
			for(int j=lst+1;j<i;j++) 
			{	
				if(t[j]=='A') y.push_back(j);
				if(t[j]=='A') cnta++; else cntb++;
				if(s[j]=='A') sa++;
				else if(s[j]=='B') sb++;
				if(t[j]=='C'&&t[i]!='C') return 0; 
			}
			if(sa>cnta||sb>cntb) return 0;
			for(int j=lst+1;j<i;j++)
			{
				if(s[j]!='C')
				{
					if(s[j]=='A') x.push_back(j);
					continue;
				}
				if(sa<cnta) sa++,x.push_back(j);
			}
			for(int j=0;j<x.size();j++) if(x[j]>y[j]) return 0;
			lst=i;
		}
	}
	return 1;
}
int main()
{
	T=read();
	while(T--)
	{
		int res=solve();
		if(res) printf("Yes\n");
		else printf("No\n");
	}
	return 0;
}

B. Make Multiples

Solution 1

容易知道令 \(x\) 成为 \(y\) 的倍数,所需的最小操作次数为 \((y-(x\bmod y))\bmod y\)
我们分别令 \(x=a,b,c,ab,bc,abc\),求每个数成为 \(x\) 的倍数所需的最小次数,并升序排序。那么当前 \(x\) 下只有操作次数最小的三个 \(a_i\) 可能被计入答案。
这样我们一共获得了至多 \(X=3\times 6=18\)\(a_i\),暴力在它们之间 \(O(X^3)\) 枚举哪三个数成为 \(a,b,c\) 的倍数,统计最小值即可。

Solution 2

考虑状压。设 \(f_{i,j}\) 表示考虑了前 \(i\) 个数,已经存在倍数的数为集合 \(j(j\in[0,2^3))\)
枚举当前数要修改成哪些数的倍数,那么有:

\[f_{i,j\cup k}\gets f_{i-1,j}+w(i,k) \]

直接转移,令 \(M=3\),时间复杂度 \(O(n 2^{2M})\)

Code
#define int long long
const int N=2e5+5;
int n,a[N],vis[N];
struct node{int id,x;} c[N];
int b[3],L[N];
vector<int> d;
il bool cmp(node x,node y) {return x.x<y.x;}
il int lcm(int a,int b) {return a*b/__gcd(a,b);} 
signed main()
{
	n=read(); 
	for(int i=0;i<3;i++) b[i]=read();
	for(int i=1;i<=n;i++) a[i]=read();
	for(int s=1;s<8;s++)
	{
		int lc=1;
		for(int i=0;i<3;i++) if((s>>i)&1) lc=lcm(lc,b[i]);
		for(int i=1;i<=n;i++) c[i].id=i,c[i].x=a[i]%lc?lc-a[i]%lc:0;
		sort(c+1,c+n+1,cmp);
		for(int i=1;i<=min(n,3ll);i++) 
			if(!vis[c[i].id]) vis[c[i].id]=1,d.push_back(a[c[i].id]);
	}
	int ans=3e18;
	for(int i=0;i<d.size();i++)
	{
		for(int j=0;j<d.size();j++)
		{
			for(int k=0;k<d.size();k++)
			{
				int res=0;
				for(int l=0;l<d.size();l++) L[l]=1;
				L[i]=lcm(L[i],b[0]),L[j]=lcm(L[j],b[1]),L[k]=lcm(L[k],b[2]);
				for(int l=0;l<d.size();l++) res+=d[l]%L[l]?L[l]-d[l]%L[l]:0;
				ans=min(ans,res);
			}
		}
	}
	printf("%lld\n",ans);
	return 0;
}

C. LU / RD Marking

把少打的半场时间补上大概能过。

Description

给一个 \(n\)\(m\) 列的网格,那么它的所有网格线上共有 \(n(m+1)\) 条竖边,\((n+1)m\) 条横边。

有如下两种操作:

  • 选一个上面和左面的网格线都没被涂黑的格子,并涂黑这两条线;
  • 选一个下面和右面的网格线都没被涂黑的格子,并涂黑这两条线。

求执行两种操作若干次(可以为 \(0\)),可能得到不同的涂黑边集数量。

\(T\le 2\times 10^5,\ n,m\le 10^6\)

Solution

在网格线上考虑问题,发现操作一次只会对该折线左下 / 右上相邻的折线产生影响。也就是说,我们把网格线斜向拆成若干条连续的折线,它们之间贡献独立。借用一下官方题解的图:

想到这一步就很好做了。

现在我们要求的就是对于每一条折线,在上面选若干长度为 \(2\) 的区间,且两两之间不能有交的方案数。

考虑 dp,设 \(f_n\) 表示长度为 \(n\) 的折线的答案。那么如果不选 \([n-1,n]\) 这条折线,\([n-2,n-1]\) 及以前的都可以选,方案数为 \(f_{n-1}\);否则只能选 \([n-3,n-2]\) 及以前的,方案数为 \(f_{n-2}\)。发现是斐波那契,预处理一下就好了。

统计一对 \((n,m)\) 的答案,这里设 \(n<m\),不满足就 \(\text{swap}\) 一下。
那么分成从横/竖边出发,把每条折线的贡献乘起来,则答案为

\[ans=(f_n)^{m-n}\times \prod_{i=1}^n (f_{2i-1})^2 \]

前面一半快速幂,后面一半预处理。

点击查看代码
#define int long long
const int N=2e6+5,mod=998244353;
int T,n,m;
int f[N],sum[N];
void init(int mx)
{
    f[0]=1,f[1]=2;
    for(int i=2;i<=mx;i++) f[i]=(f[i-1]+f[i-2])%mod;
    sum[0]=1;
    for(int i=1;i<=(mx>>1);i++) sum[i]=sum[i-1]*f[2*i-1]%mod*f[2*i-1]%mod;
}
il int qpow(int n,int k)
{
    int res=1;
    for(;k;n=n*n%mod,k>>=1) if(k&1) res=res*n%mod;
    return res;
}
signed main()
{
    init(2e6);  
    T=read();
    while(T--)
    {
        n=read(),m=read();
        if(n>m) swap(n,m);
        int res=sum[n];
        res=res*qpow(f[2*n],m-n)%mod;
        printf("%lld\n",res);
    }
    return 0;
}

D. Interval Counts

这不比 C 简单。

Description

给定正整数 \(n\) 和长度为 \(n\) 的序列 \(x_i,y_i\),保证 \(x_i\) 单调递增。你要构造 \(m\) 个区间 \([L_i,R_i]\)(\(m\) 由你指定),使每个 \(x_i\) 恰好被 \(y_i\) 个区间包含。

求所有构造方案中 \(\min_{i=1}^m \{R_i-L_i\}\) 的最大值。

\(N\le 2\times 10^5,\ 1\le x_i,y_i\le 10^9\)

Solution

看到最小值最大试图进行二分,然而不太可做。因此考虑直接贪心构造。

\(x_i\) 从小到大的顺序依次构造区间。
假设当前构造的区间已经满足 \(x_1,\dots,x_{i-1}\) 的限制。那么根据当前 \(y_i\)\(y_{i-1}\) 的大小关系分为三种情况。

  • \(y_i=y_{i-1}\) 是容易处理的,因为我们什么也不用做,把上一次的区间都延长过来就可以。

  • \(y_i<y_{i-1}\),我们不能把所有未确定右端点的区间都接过来,必须要断掉恰好 \(d=y_{i-1}-y_i\) 条边。根据想让最短区间最长的目标,断掉左端点前 \(d\) 小的线段是最优的。所以把左端点前 \(d\) 小的线段右端点设为 \(x_i-1\),把它们移出未确定右端点的区间集合并更新答案。

  • \(y_i>y_{i-1}\),那么缺 \(d=y_i-y_{i-1}\) 个区间。令它们左端点最小,则新增 \(d\) 个左端点为 \(x_{i-1}+1\),右端点未确定的区间,加入集合。

由于 \(y\le 10^9\)\(m\) 很大,暴力维护所有左端点不可行。但发现每次我们加入集合的左端点都单调递增,用一个队列存储二元组 \((x,y)\) 表示插入了 \(y\) 条左端点为 \(x\) 的区间。删除的时候弹队首即可,时间复杂度 \(O(n)\)

点击查看代码
const int N=2e5+5,inf=1e9;
int n,x[N],y[N];
pii q[N];
int st=1,ed=0,ans=inf;
int main()
{
    n=read();
    for(int i=1;i<=n;i++) x[i]=read();
    for(int i=1;i<=n;i++) y[i]=read();
    x[0]=-inf;
    for(int i=1;i<=n;i++)
    {
        if(y[i]==y[i-1]) continue;
        if(y[i]>y[i-1]) q[++ed]=pii(x[i-1],y[i]-y[i-1]);
        else
        {
            int now=y[i-1]-y[i];
            while(st<=ed&&q[st].se<=now)
            {
                ans=min(ans,x[i]-q[st].fi-1);
                now-=q[st].se,st++;
            }
            if(st<=ed&&now&&q[st].se>now) q[st].se-=now,ans=min(ans,x[i]-q[st].fi-1);
        }
    }
    if(ans==inf) printf("-1\n");
    else printf("%d\n",ans-1);
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1075272.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LVGL_基础控件timer

LVGL_基础控件timer 1、创建基础控件定时器 /* 下面创建三个timer&#xff0c;最后创建的timer会被放在timer list的最前面&#xff0c; lvgl的任务处理器会从timer list从头到尾按顺序遍历检查&#xff0c;执行满足执行条件的timer。 因此&#xff0c;如果三个定时器的周期设…

帮微软语音助手纠正“阿弥陀佛”“e”字错误发音的技巧

一、前言 微软AI文字转语音助手&#xff0c;现已被大家普便应用。最近在传统文化佛学名词的发音转换应用中&#xff0c;发现了一个致命的错误。那就是“阿弥陀佛”中的“阿”字的“a”发音&#xff0c;被误读为“e”。说起这个重大的错误&#xff0c;佛门大德南怀瑾老师也一再…

排序算法——选择排序

一、介绍&#xff1a; 选择排序就是按照一定的顺序从选取第一个元素索引开始&#xff0c;将其储存在一个变量值中&#xff0c;根据排序规则比较后边每一个元素与这个元素的大小&#xff0c;根据排序规则需要&#xff0c;变量值的索引值进行替换&#xff0c;一轮遍历之后&#x…

【RabbitMQ】docker rabbitmq集群 docker搭建rabbitmq集群

docker rabbitmq集群 docker搭建rabbitmq集群 RabbitMQ提供了两种常用的集群模式 1.普通集群模式 2.镜像集群模式 普通集群模式只能同步主节点上的交换机和队列信息&#xff0c;但对于队列中的消息不做同步&#xff0c;主节点宕机也不能进行切换&#xff08;故障转移&#xff…

socket can查看详细信息 命令 ip -details -statistics link show can0

ip -details -statistics link show can0 ip -details link show can0 ip -statistics link show can0 也可以像第一行那样结合使用

C语言应用:Linux与Windows的系统化

作为一种广泛应用于软件开发的编程语言&#xff0c;C语言在工业应用领域也发挥着重要的作用。在本文中&#xff0c;我们将深入探索C语言在工业应用中的应用场景和价值&#xff0c;并重点关注它在Linux和Windows系统中的工业化之路。希望本文能为您介绍C语言在工业领域的实际应用…

SpringBoot-黑马程序员-学习笔记(二)

22.读取yaml文件中的属性 3个步骤&#xff1a; 1.写yaml文件 2.在控制类里面定义变量 3.在变量上面用 " Value注解 ${} " 获取yaml文件的属性 代码演示&#xff1a; yaml文件 控制类&#xff1a; 访问网址books后&#xff1a; 读取到了对应了值 23.yaml文件中…

msvcp120.dll文件下载安装,学习msvcp120.dll文件三种重新安装方法

在计算机使用过程中&#xff0c;我们可能会遇到各种意想不到的问题&#xff0c;其中 msvcp120.dll 丢失就是一种比较常见的情况。msvcp120.dll 是微软 Visual Studio 2013 编译的程序所依赖的一个动态链接库文件&#xff0c;它包含了 C标准库的一些功能&#xff0c;如输入输出、…

QT信号与槽机制 和 常用控件介绍

QT信号与槽机制 1、信号(signal): 所谓信号槽 (观察者模式)信号本质是事件。信号展现方式就是函数。当某一个事件发生之后&#xff0c;则发出一个信号(signal). 2、槽(slot): 就是对信号响应的函数&#xff0c;槽就是一个函数。槽函数与普通函数区别槽函数可以与一个信号关联&…

Bootstrap中固定某一个元素不随滚动条滚动

可以利用类sticky-top实现固定某个元素在顶部的效果&#xff0c;示例代码如下&#xff1a; <!DOCTYPE html> <html> <head><meta charset"UTF-8"><title>固定某一个元素不随滚动条滚动</title><meta name"viewport&quo…

vue3 antv 静态登录页面

效果图 <template> <!-- 内容区域 --><div class"main"><div class"from"><!-- 表单 model是antv里边的绑定表单数据 --><a-form :model"formState" ref"formRef"><!-- 切换 --><a-tabs…

06-进程间通信

学习目标 熟练使用pipe进行父子进程间通信熟练使用pipe进行兄弟进程间通信熟练使用fifo进行无血缘关系的进程间通信使用mmap进行有血缘关系的进程间通信使用mmap进行无血缘关系的进程间通信 2 进程间通信相关概念 2.1 什么是进程间通信 Linux环境下&#xff0c;进程地址空间…

FPGA设计时序约束四、多周期约束

目录 一、背景 二、set_multicycle_path a)Targets界面 b)options界面 c)setup与hold关系 三、多周期约束场景 3.1 单时钟域的多周期约束 3.2 多周期路径与时钟相移 3.3 慢时钟到快时钟的多周期约束 3.4 快时钟到慢时钟的多周期约束 四、工程示例 五、参考 一、背景…

广州华锐互动:VR互动教学平台如何赋能职业院校?

随着科技的发展&#xff0c;我们的教育方式也在不断进步。其中&#xff0c;虚拟现实&#xff08;VR&#xff09;技术的出现为我们提供了一种全新的教学方式。特别是在职业学校中&#xff0c;VR互动教学平台已经成为一种重要的教学工具。 VR互动教学平台是一种利用虚拟现实技术创…

游戏软件开发与应用软件开发有什么不同呢?

游戏软件开发和应用软件开发是两种不同类型的软件开发&#xff0c;它们在许多方面都有不同之处。以下是它们之间的一些主要区别&#xff1a; 目标用户群体&#xff1a; 游戏软件开发的主要目标是提供娱乐和休闲体验&#xff0c;通常面向广大的游戏玩家群体。游戏软件的设计和开…

【java基础学习】之DOS命令

#java基础学习 1.常用的DOS命令&#xff1a; dir:列出当前目录下的文件以及文件夹 md: 创建目录 rd:删除目录cd:进入指定目录 cd.. :退回到上级目录 cd\ : 退回到根目录 del:删除文件 exit:退出dos命令行 1.dir:列出当前目录下的文件以及文件夹 2.md: 创建目录 …

Spring实例化源码解析之Custom Events上集(八)

Events使用介绍 在ApplicationContext中&#xff0c;事件处理通过ApplicationEvent类和ApplicationListener接口提供。如果将实现ApplicationListener接口的bean部署到上下文中&#xff0c;每当一个ApplicationEvent被发布到ApplicationContext时&#xff0c;该bean将被通知。…

Android Studio版本升级后的问题 gradle降级、jdk升级

Cannot use TaskAction annotation on method IncrementalTask.taskAction$gradle_core() because interface org.gradle.api.tasks.incremental.IncrementalTaskInputs is not a valid parameter to an action method. 修改下面两处地方分别为7.0.3、7.3.3Android Gradle plu…

Nginx的跨域问题解决

同源策略 浏览器的同源策略&#xff1a;是一种约定&#xff0c;是浏览器最核心也是最基本的安全功能&#xff0c;如果浏览器少了同源策略&#xff0c;则浏览器的正常功能可能都会受到影响。 同源: 协议、域名(IP)、端口相同即为同源 跨域问题 有两台服务器分别为A,B,如果从…

网络安全(自学黑客技术)——黑客学习方法

如果你想自学网络安全&#xff0c;首先你必须了解什么是网络安全&#xff01;&#xff0c;什么是黑客&#xff01;&#xff01; 1.无论网络、Web、移动、桌面、云等哪个领域&#xff0c;都有攻与防两面性&#xff0c;例如 Web 安全技术&#xff0c;既有 Web 渗透2.也有 Web 防…