agc020D Min Max Repetition
多组询问。每个询问给定四个整数, A , B , C , D A,B,C,D A,B,C,D,求一个满足这个条件的字符串:
- 长度为
A
+
B
A+B
A+B,由
A
A
A个字符
A和 B B B个字符B构成。 - 在此基础上,连续的相同字符个数的最大值最小
- 在此基础上,字典序最小
输出这个字符串的第 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');
}
}


被折叠的 条评论
为什么被折叠?



