• 「AGC020D」 Min Max Repetition


    「AGC020D」 Min Max Repetition

    传送门

    首先这个东西的连续字符个数你可以二分。但事实上没有必要,这是可以直接算出来的。

    (k=max{lceilfrac{A}{B+1} ceil,lceilfrac{B}{A+1} ceil})

    证明你就考虑把每一个 B 或者 A 分成一段过后另一种最少每段放几个。

    然后接下来就非常神奇,由于要求字典序最小,这个字符串一定形如 ( exttt{AAA...BAAA...BAAA...BBB...ABBB...A})

    然后可以二分两种类型分割的边界,然后暴力check能不能填的上就完事了。

    当然这里存在方法可以通过分类讨论来做到不需二分。

    /*---Author:HenryHuang---*/
    /*---Never Settle---*/
    #include<bits/stdc++.h>
    using namespace std;
    int a,b,c,d,k;
    bool check(int mid){
    	int u=a-mid/(k+1)*k-mid%(k+1);
    	int v=b-mid/(k+1);
    	return 1ll*v<=1ll*u*k;
    }
    int main(){
    	ios::sync_with_stdio(0);
    	cin.tie(0),cout.tie(0);
    	int T;cin>>T;
    	while(T--){
    		cin>>a>>b>>c>>d;
    		k=max(ceil(1.0*a/(b+1)),ceil(1.0*b/(a+1)));
    		int l=0,r=a+b+1;
    		while(l<r){
    			int mid=(l+r)>>1;
    			if(check(mid)) l=mid+1;
    			else r=mid;
    		}
    		int u=a-l/(k+1)*k-l%(k+1);
    		int v=b-l/(k+1);
    		r=l+v-u*k+1;
    		for(int i=c;i<=min(d,l);++i){
    			if(i%(k+1)) cout<<"A";
    			else cout<<"B";
    		}
    		for(int i=max(c,l+1);i<=d;++i){
    			if((i-r)%(k+1)) cout<<"B";
    			else cout<<"A";
    		}
    		cout<<'
    ';
    	}
    	return 0;
    }
    
    在繁华中沉淀自我,在乱世中静静伫立,一笔一划,雕刻时光。
  • 相关阅读:
    Blank_Model
    C++基础知识string,set,队列,栈
    c++ pow 求幂函数
    c++ 函数传参
    c++基础知识pair,make_pair
    c++基础知识vector
    c++ %和/
    c++01背包问题:
    c++基础知识哈希表
    开发基本步骤(高阶必修)
  • 原文地址:https://www.cnblogs.com/HenryHuang-Never-Settle/p/solution-AGC020D.html
Copyright © 2020-2023  润新知