zoukankan      html  css  js  c++  java
  • 【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
  • 相关阅读:
    [BZOJ1433][luogu_P2055][ZJOI2009]假期的宿舍
    [BZOJ1280][POJ1149]Emmy卖猪pigs
    [BZOJ1066][luogu_P2472][SCOI2007]蜥蜴
    [nowcoder_Wannafly挑战赛4_F]线路规划
    [SPOJ839]Optimal Marks
    [BZOJ1497][NOI2006]最大获利
    Django_orm脚本
    Function
    Class
    Python核心编程
  • 原文地址:https://www.cnblogs.com/onioncyc/p/8287050.html
Copyright © 2011-2022 走看看