2017 ACM西安网络赛 E题 Maximum Flow

本文通过一组小数据网络流的计算结果揭示了其背后的规律,并提供了一段C++代码实现,该规律显示了每组数据中特定数字的周期性出现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

小数据跑网络流,
得到答案如下:

NN=2 flow=1
NN=3 flow=3 2
NN=4 flow=5 2
NN=5 flow=10 5
NN=6 flow=12 2
NN=7 flow=17 5
NN=8 flow=19 2
NN=9 flow=36 17
NN=10 flow=38 2
NN=11 flow=43 5
NN=12 flow=45 2
NN=13 flow=62 17
NN=14 flow=64 2
NN=15 flow=69 5
NN=16 flow=71 2
NN=17 flow=136 65
NN=18 flow=138 2
NN=19 flow=143 5
NN=20 flow=145 2
NN=21 flow=162 17
NN=22 flow=164 2
NN=23 flow=169 5
NN=24 flow=171 2
NN=25 flow=236 65
NN=26 flow=238 2
NN=27 flow=243 5
NN=28 flow=245 2
NN=29 flow=262 17
NN=30 flow=264 2
NN=31 flow=269 5
NN=32 flow=271 2
NN=33 flow=528 257
NN=34 flow=530 2
NN=35 flow=535 5
NN=36 flow=537 2
NN=37 flow=554 17
NN=38 flow=556 2
NN=39 flow=561 5
NN=40 flow=563 2
NN=41 flow=628 65
NN=42 flow=630 2
NN=43 flow=635 5
NN=44 flow=637 2
NN=45 flow=654 17
NN=46 flow=656 2
NN=47 flow=661 5
NN=48 flow=663 2
NN=49 flow=920 257
NN=50 flow=922 2
NN=51 flow=927 5
NN=52 flow=929 2
NN=53 flow=946 17
NN=54 flow=948 2
NN=55 flow=953 5
NN=56 flow=955 2
NN=57 flow=1020 65
NN=58 flow=1022 2
NN=59 flow=1027 5
NN=60 flow=1029 2
NN=61 flow=1046 17
NN=62 flow=1048 2
NN=63 flow=1053 5
NN=64 flow=1055 2
NN=65 flow=2080 1025
NN=66 flow=2082 2
NN=67 flow=2087 5
NN=68 flow=2089 2
NN=69 flow=2106 17
NN=70 flow=2108 2
观察答案的增量,存在一定的规律。
将之分组,规律比较明显:
2
2 5
2 5 2 17
2 5 2 17 2 5 2 65
2 5 2 17 2 5 2 65 2 5 2 17 2 5 2 257

在第一组中,只有一个2;
第二组中,每2个数出现一个5;
第三组中,每2个数出现一个5,每4个数出现一个17;
第四组中,每2个数出现一个5,每4个数出现一个17,每8个数出现一个65;
第五组中,每2个数出现一个5,每4个数出现一个17,每8个数出现一个65,每16个数出现一个257;
2=2^0+1, 5=2^2+1, 17=2^4+1, 257=2^8+1;
代码如下:

#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#define debug puts("Infinity is awesome!")
#define mm(a, b) memset(a, b, sizeof(a))
#define LL long long
using namespace std;
const int maxn=1e3+5;
const LL mod=1e9+7;
const double eps=1e-8;
LL f[maxn];
void Pre(){
    f[0]=1LL;
    for(int i=1;i<200;i++)
        f[i]=(f[i-1]<<1)%mod;
}
int main(){
    int T;
    int cas=0;
    LL n;

    Pre();
    while(~scanf("%lld", &n)){
        n--;
        if(n==1){printf("1\n"); continue;}
        LL ans=1; n--;
        for(int i=0;i<64&&n>0;i++){
            LL cnt=(n>>i)%mod;
            LL tmp=(f[2*i]+1)%mod;
            ans=(ans+cnt*tmp%mod)%mod;
            if(i){
                tmp=(f[2*(i-1)]+1)%mod;
                ans=(ans-cnt*tmp%mod+mod)%mod;
            }
            n-=(1LL<<i);
        }
        printf("%lld\n", ans);
    }

    return 0;
    //今天完全挂机态,对不起队友。
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值