agc011_d Half Reflector (找规律)

这题好有趣啊,玩了好一会儿才得出比较简洁的做法。

记A状态为1(黑),B状态为0(白)。

发现几个比较有用的规律:

(1)一个球通过一段长度为L的黑块时,会把前L-1个黑块都变成白块。

        特殊情况:这段黑块在最左边,那么球只会把第一个黑块取反,然后从左端飞回去;

(2)一个球通过一段长度为L的白块时,会把前L-1个白块都变成黑块;

       特殊情况:这段白块在最右边,那么球会把所有白块都取反,直接从右端飞出。

这样我们的模拟过程就没原来那么烧脑了。

然而这样还是很复杂啊,根本没法推那么多步。

继续画样例,发现更有用的规律:

最左边的块为白块时,一个球飞进来,改变效果如下:

0011100001111000111

1000111100001110001

其实就是把红色的部分往前移动了一格,并且全部取反!

并且再移动几次,我们又可以发现蓝色部分的规律:

1000111100001110001

1110000111100011101

0011110000111000101

1000011110001110101

……

忽略开头为1时的操作,我们只要执行n次,蓝色部分就会侵占整个序列,

n为偶数时,序列是0101....0101,压根就不会再发生变化,所以直接就知道k次之后的结果;

n为奇数时,序列是10101...0101,除了第一位不断闪烁变化,后面也都不会变。所以根据奇偶判断第一位,后面直接输出即可。

因此,我们至多模拟2n次。

还有一些细节,就是怎么O(1)维护一次操作。

我们直接修改太慢了,不妨维护一个头指针p,表示红色部分的开头是初始串的第几位,再维护一个取反标记rev,rev=1表示红色集体取反,rev=0表示红色部分不取反,开头是1则执行:a[p]^=1;开头是0则执行:p++,rev^=1。

复杂度O(n)。

#include <cstdio>
#include <cstring>
#define rep(i,j,k) for (i=j;i<=k;i++)
using namespace std;
const int N=2e5+5;
int n,k,i,j,p,rev,a[N];
char s[N];
void trans(int x) { if (x) putchar('A'); else putchar('B'); }
int main()
{
	scanf("%d%d%s",&n,&k,s+1);
	rep(i,1,n) if (s[i]=='A') a[i]=1; else a[i]=0;
	for (j=0,p=1;j<k && p<=n;j++) {
		if (a[p]^rev) {a[p]^=1; continue;}
		rev^=1; p++;
	}
	if (j>=k) {
		rep(i,p,n) trans(a[i]^rev);
		rep(i,n+1,n+p-1) trans((n+p-i)&1);
	}
	else {
		if (n&1) {
			trans((k-j+1)&1);
			rep(i,2,n) trans(i&1);
		}
		else rep(i,1,n) trans((i+1)&1);
	}
	return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
reflector_jb51是一款功能强大的反射工具,它能帮助开发者在调试和分析代码时查看类、方法和属性的信息。它可以通过反射功能读取应用程序集中的元数据并显示出来,让开发者可以更好地理解代码结构和实现细节。 reflector_jb51相比其他反射工具来说有很多优点。首先,它界面简洁直观,操作方便快捷。用户只需要将要反射的应用程序集导入到工具中,就可以立即查看其中的类和成员信息,而不需要进行繁琐的配置和设置。 其次,reflector_jb51支持多种编程语言,包括C#、VB.NET、Java等,使开发者可以在同一个工具中处理不同语言的代码。这样就方便了开发者在跨平台或多语言项目中进行分析和调试。 另外,reflector_jb51还提供了多种功能,如查看IL代码、反编译、搜索和过滤等,使开发者能够深入了解代码的执行过程和逻辑。比如,开发者可以通过查看IL代码来了解编译后的实际执行方式,或者通过反编译将编译后的代码还原成源代码进行分析。 除了以上优点,reflector_jb51还具备很高的可扩展性。它支持插件机制,可以通过安装插件来扩展工具的功能,满足不同开发者的需求。 综上所述,reflector_jb51是一款功能强大、界面简洁、支持多种语言、提供多种功能的反射工具。它极大地方便了开发者对代码进行调试和分析,是开发工具中的一把锋利的利器。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值