zoukankan      html  css  js  c++  java
  • 「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;
    }
    
    在繁华中沉淀自我,在乱世中静静伫立,一笔一划,雕刻时光。
  • 相关阅读:
    [题解]北京2018
    [数据结构][字典树]Word Puzzles
    [数据结构][字典树]Hardwood Species
    [数学][广义欧拉定理]上帝与集合的正确用法
    Equal Sums
    Useful Decomposition
    网络流 EK算法
    线段树各类操作
    唯一分解定理
    Kuro and Walking Route
  • 原文地址:https://www.cnblogs.com/HenryHuang-Never-Settle/p/solution-AGC020D.html
Copyright © 2011-2022 走看看