zoukankan      html  css  js  c++  java
  • CF1202F You Are Given Some Letters...

    codeforces

    有一个很显然的(O(a+b))的做法可以想到,就是枚举(k),然后(O(1))判断

    如何(O(1))判断,我们显然考虑将这个序列每(k)个分一个块,只要判断存不存在合法方案就行了

    其实这个时候很显然就能想到整除分块了,所以复杂度已经优化到(O(sqrt{a+b}))

    判断的方法为:

    我们需要满足每个块都能放满,并且每个块中( m A)( m B)的数量相等

    (n)为总长度,(m)为完整的块数,(s_a)为每个块中的(A)的数量,(s_b)为每个块中(B)的数量

    [n=a+b,m=lfloorfrac{n}{k} floor\ s_a+s_b=k\ s_a*m<=a,s_b*m<=b\ s_a<=lfloorfrac{a}{m} floor,s_b<=lfloorfrac{b}{m} floor\ a-s_a*m<=s_a,b-s_b*m<=s_b\ s_a>=lceilfrac{a}{m+1} ceil,s_b>=lceilfrac{b}{m+1} ceil\ ]

    [lceilfrac{a}{m+1} ceil<=s_a<=lfloorfrac{a}{m} floor\lceilfrac{b}{m+1} ceil<=s_b<=lfloorfrac{b}{m} floor ]

    然后计算有多少合法的(k)就好了

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    #define rg register
    void read(int &x){
        char ch;bool ok;
        for(ok=0,ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-')ok=1;
        for(x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());if(ok)x=-x;
    }
    const int maxn=1e5+10;
    int a,b,n,ans;
    int main(){
        read(a),read(b);n=a+b;
        for(rg int i=1,j;i<=n;i=j+1){
    	j=n/(n/i);int t=n/i;
    	if(a<t||b<t)continue;
    	int al=a/(t+1)+(a%(t+1)!=0),ar=a/t;
    	int bl=b/(t+1)+(b%(t+1)!=0),br=b/t;
    	if(al<=ar&&bl<=br)ans+=max(0,min(j,ar+br)-max(i,al+bl)+1);
        }
        printf("%d
    ",ans);
    }
    
  • 相关阅读:
    迷宫城堡 HDU
    Strategic game POJ
    Warm up HDU
    Network POJ
    Delphi Tstream 流
    Delphi 获得文件大小的五种方法
    Delphi Messagebox 介绍
    delphi idftp
    Delphi 操作Excel
    Delphi 打印对象 Tprinter 常用属性、方法、函数、打印示例
  • 原文地址:https://www.cnblogs.com/lcxer/p/11401284.html
Copyright © 2011-2022 走看看