• 【Atcoder】AGC 020 D


    【题意】定义f(A,B)为一个字符串,满足:

    1.长度为A+B,含有A个‘A',B个'B'。

    2.最长的相同字符子串最短。

    3.在满足以上2条的情况下,字典序最小。

    例如, f(2,3) = BABAB, and f(6,4) = AABAABAABB.

    Q次询问f(Ai,Bi)的子串[Ci,Di]。

    Q<=10^3,A,B<=5*10^8,D-C+1<=100,time=2s。

    【算法】二分+构造

    【题解】参考:Editorial

    令k为最短的最长相同字符子串,显然k=max(A,B)/(min(A,B)+1)(上取整)。

    考虑某个位置填入’A‘后合法,应满足:

    1.当前连续A不超过k。

    2.剩余的A’和B'构成的k(A',B')<=k(A,B)。

    顺序扫描即可得到全串——部分分。

    分析答案串的构造,前面应为A...ABA...ABA...A,直到某个位置p不满足B<=A*k为止。

    此时位置p一定是‘A',且B-A*k<=k,后面就不得不排列成B...BAB...BAB...B。

    二分位置p,输出c~d即可。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int T,k,n,a,b,c,d;
    int main(){
        scanf("%d",&T);
        while(T--){
            scanf("%d%d%d%d",&a,&b,&c,&d);n=a+b;
            int l=0,r=n+1,mid,A,B;k=(max(a,b)-1)/(min(a,b)+1)+1;;
            while(l<r){
                mid=(l+r)>>1;
                A=a-mid/(k+1)*k-mid%(k+1);B=b-mid/(k+1);
                if(B<=1ll*A*k)l=mid+1;else r=mid;
            }
            A=a-l/(k+1)*k-l%(k+1);B=b-l/(k+1);r=l+B-A*k+1;
            for(int i=c;i<=min(d,l);i++)putchar(i%(k+1)?'A':'B');
            for(int i=max(c,l+1);i<=d;i++)putchar((i-r)%(k+1)?'B':'A');
            puts("");
        }
        return 0;
    }//ONION_CYC QwQ
    View Code
  • 相关阅读:
    WikiPedia技术架构学习笔记
    MySQL 架构设计篇 (十二) 可扩展设计的基本原则
    php前端控制器二
    php前端控制器三
    构建可扩展的WEB站点读书笔记
    发布脚本开发框架代码
    改良dbgrideh的文字过滤
    cxgrid在当前View插入记录
    生成不重复单据编号
    cxgrid按条件计算合计值
  • 原文地址:https://www.cnblogs.com/onioncyc/p/8287050.html
Copyright © 2020-2023  润新知