2017 ACM-ICPC 亚洲区(西安赛区)网络赛 Maximum Flow

来源:互联网 发布:淘宝内部优惠群怎么做 编辑:程序博客网 时间:2024/06/05 20:31

原题链接:https://nanti.jisuanke.com/t/17118

题目大意:有一个网络流的图,点的标号为从0到N-1,点i , j( i<j)之间存在一条从i到 j 的容量为  i xor j 的有向边,

问从0到N-1的最大流是多少。

假设2^k<=N-1<x^(k+1),则对于 0<=i<=2^k-1,点0到点i的流量小于2^k,而点i到点N-1的边的容量不小于2^k,所以这些点到N-1的总流量就是i

对于2^k<= i <= N-1 ,这些点到点N-1的边的容量不大于2^k,而点0到点i的流量不小于2^k,所以点i到N-1的总流量就是(N-1) xor i 。

代码:

#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>#define ll long longusing namespace std;inline void read(long long &x){    char ch;    bool flag=false;    for (ch=getchar();!isdigit(ch);ch=getchar())if (ch=='-') flag=true;    for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());    x=flag?-x:x;}inline void write(int x){    static const int maxlen=100;    static char s[maxlen];        if (x<0){putchar('-'); x=-x;}    if(!x){ putchar('0'); return; }    int len=0; for(;x;x/=10) s[len++]=x % 10+'0';    for(int i=len-1;i>=0;--i) putchar(s[i]);}const long long P=1000000007ll;const long long ny2=500000004ll;long long n;long long get_num(long long  x){if (x==0)    return 0;long long kk=1;while ( kk<x)    kk=kk*2;if ( kk>x)    kk=kk/2;return ( (  ( ( (kk-1)%P) *(kk%P)%P ) *( ny2%P)%P )%P+ (kk%P)*( kk%P)%P + get_num(x-kk)%P )%P;}long long get_ans(long long x){if (x==0)    return 0;long long kk=1;while ( kk<x)    kk=kk*2ll;if ( kk>x)    kk=kk/2ll;long long T=get_num(x-kk)%P;return ( ( ( ( (  (kk-1)%P ) * ( kk%P ) )%P )*( ny2%P )%P )%P +T%P+x%P )%P;}int main(){        while ( scanf("%lld",&n)!=EOF)            cout<<get_ans(n-1)<<endl;return 0;}


阅读全文
0 0
原创粉丝点击