zoukankan      html  css  js  c++  java
  • 【GDOI2018】D1T1 农场分割(farm)

    题目大意

      n个数,求最多分成几组,使每组的和一样。

    Solution of mine

      简单可见n个数的总和一定能被组数整除。

      首先预处理第$i$位向后$2^j$个数的和。

      对于总和$sum$的每个因子x,我们执行$sum/x$次倍增查找下一个位置是否分割点。

      复杂度O(因子个数和)

      因为因子个数和上界是$O(n log n)$,而且卡不满,所以$10^6$就卡过去了。

    Solution of std

      延续上面的思想。

      我们发现可以用前缀和的思想来判断某个位置是否是分割点。

      用一个bool数组$f$储存前缀和i是否出现。

      如果

       $sum_{i=1}^{frac{sum}{i}}[f[i]]=frac{sum}{i}$

      则代表该ans可行。

    AC Code

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cctype>
    #include <algorithm>
    #define MAXBUF 50000000
    using namespace std;
    char buffer[MAXBUF];
    int pos;
    inline void load(){
        fread(buffer,1,MAXBUF,stdin);
        pos=0;
    }
    inline char gchar(){
        return buffer[pos++];
    }
    inline int rd(){
        int ret=0;char c=gchar();
        for(;!isdigit(c);)c=gchar();
        for(;isdigit(c);)ret=ret*10+c-'0',c=gchar();
        return ret;
    }
    int n,x,ans,sum;
    bool f[1000010];
    inline bool check(int ans){
        for(int j=1;j<=(sum/ans);j++)
            if(!f[ans*j])
                return 0;
        return 1;
    }
    int main(){
        freopen("farm.in","r",stdin);
        freopen("farm.out","w",stdout);
        load();
        n=rd();
        for(int i=1;i<=n;i++){
            x=rd();
            sum+=x;
            f[sum]=1;
        }
        for(int i=1;i<=sum;i++)
            if(sum%i==0)
                if(check(i)){
                    ans=i;
                    break;
                }
        printf("%d
    ",sum/ans);
        return 0;
    }

      

     

  • 相关阅读:
    10 个你需要了解的 Linux 网络和监控命令
    U盘安装 bt5
    SpringCloud RabbitMQ 使用
    两个大数相乘笔试题目
    activemq 话题模式(三)
    activemq 队列模式(二)
    activemq 安装 (一)
    安装mysql5.7时缺少my.ini文件
    linux 远程rsa 登录配置 文件 /etc/ssh/sshd_config
    java -jar 解决占用终端问题
  • 原文地址:https://www.cnblogs.com/skylynf/p/8974097.html
Copyright © 2011-2022 走看看