agc020D Min Max Repetition

agc020D Min Max Repetition

多组询问。每个询问给定四个整数, A , B , C , D A,B,C,D A,B,C,D,求一个满足这个条件的字符串:

  1. 长度为 A + B A+B A+B,由 A A A个字符A B B B个字符B构成。
  2. 在此基础上,连续的相同字符个数的最大值最小
  3. 在此基础上,字典序最小

输出这个字符串的第 C C C位到第 D D D位。

Solution

  • 答案可以通过选择少数的字符作为间隔数计算得到。

  • 可以证明,确定答案为s时,最后的串为: A . . A B ( n ) + A . . B . . + A B . . B ( m ) A..AB(n)+A..B..+AB..B(m) A..AB(n)+A..B..+AB..B(m)

  • 前面和后面的每一段的 A , B A,B A,B个数都为 s s s,剩下的即为中间的,连续数都小于 s s s

  • 然后就可以 O ( 1 ) O(1) O(1)知道某个位置了。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;

int Q,A,B,L,R,i,j,k;

int main(){
	freopen("ceshi.in","r",stdin);
	scanf("%d",&Q);
	while (Q--){
		scanf("%d%d%d%d",&A,&B,&L,&R);
		if (abs(A-B)<=1) {
			if (B>A) for(i=L;i<=R;i++) putchar('A'+(i&1));
			else for(i=L;i<=R;i++) putchar('A'+(i&1^1));
		} else {
			ll s;
			if (A>B) s=(A+B)/(B+1);
			else s=(A+B)/(A+1);
			ll c1=(s*A-B+1+(s*s-1-1))/(s*s-1)-1;
			ll c2=(s*B-A+1+(s*s-1-1))/(s*s-1)-1;
			ll res1=A-c1*s-c2,res2=B-c1-c2*s;
			for(i=L;i<=R;i++) 
				if (i<=c1*(s+1)) putchar('A'+(i%(s+1)==0)); else 
				if (A+B-i+1<=c2*(s+1)) putchar('B'-((A+B-i+1)%(s+1)==0)); else {
					if (i-c1*(s+1)<=res1) putchar('A');
					else putchar('B');
				}
		}
		putchar('\n');
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值