Maximum Flow(2017 ACM-ICPC 亚洲区(西安赛区)网络赛 E)
Problem Description
Given a directed graph with?nn?nodes, labeled 0,1,?,n?1.
For each?<i, j>?satisfies 0≤i<j<n, there exists an edge from the i-th node to the j-th node, the capacity of which is?i?xor?j.
Find the maximum flow network from the 0-th node to the (n-1)-th node, modulo?1000000007.
Input
Multiple test cases (no more than 10000).
In each test case, one integer in a line denotes n(2≤n≤10^18?).
Output
Output the maximum flow modulo 11000000007 for each test case.
???????Sample?Input
2
???????Sample?Output
1
題意:多組數據,每組給出一個數 n,代表有 n 個編號從 0 到 n-1 的點,現在對于這 n 個點,當 i<j 時,兩點之間存在一條邊,其邊容量為 i^j,問從 0 到 n-1 的最大流
思路:
多畫幾組樣例可以發現,0 到 n-1 兩點之間必須要割
對于任意一個 i,0 到 i?與 i 到 n?1 至少要割一個,因此考慮 i 在 n?1?的最高位是否為 0 即可,若最高位為 0 就割 0 到 i,否則就割 i 到 n?1
在圖中經過這樣的割后,一定存在一個分界線 100...00,使得前面所有的點與 n-1 連通不與 0 連通,后面所有的點與 0 連通不與 n-1 連通,這樣 0 與 n-1 就隔開了
于是問題就轉換成了求割下來的各條邊的流量和,從 i 個最高位考慮:
若 i 的最高位為 0 時,割為 0 到 i,其流量和就是 1+2+...+(2^(len-1)-1)
當 i?的最高位為 1 時,割為 i 到 n?1,考慮從低位向高位找 n?1 中除最高位外為 1?的位,設當前為第 j 位,那么可對從最高位到第?j+1 位與?n-1 相同且第 j 位為 0 的數求和
對于這些數,j-1 位到 0 位于 n-1 的異或值就是 1+2+...+(2^(j-1)-1),第 j 位與 n-1 的異或值為 2^j,最高位到第 j+1 位與 n-1 的異或值為 0
Source Program
#include<iostream> #include<cstdio> #include<cstdlib> #include<string> #include<cstring> #include<cmath> #include<ctime> #include<algorithm> #include<utility> #include<stack> #include<queue> #include<vector> #include<set> #include<map> #include<bitset> #define PI acos(-1.0) #define INF 0x3f3f3f3f #define LL long long #define Pair pair<int,int> LL quickPow(LL a,LL b){ LL res=1; while(b){if(b&1)res*=a; a*=a; b>>=1;} return res; } LL quickModPow(LL a,LL b,LL mod){ LL res=1; a=a%mod; while(b){if(b&1)res=(a*res)%mod; a=(a*a)%mod; b>>=1;} return res; } LL getInv(LL a,LL mod){ return quickModPow(a,mod-2,mod); } // (a/b)%MOD=(a%MOD * getInv(b)%MOD)%MOD const double EPS = 1E-10; const int MOD = 1E9+7; const int N = 100000+5; const int dx[] = {-1,1,0,0,-1,-1,1,1}; const int dy[] = {0,0,-1,1,-1,1,-1,1}; using namespace std;int main() {LL n;while(scanf("%lld",&n)!=EOF){if(n==2)printf("1\n");else{n--;LL temp=n;int len=0;while(temp){len++;temp/=2;}LL temp1=quickModPow(2,len-2,MOD);LL temp2=(quickModPow(2,len-1,MOD)-1+MOD)%MOD;LL res=(temp1%MOD*temp2%MOD)%MOD;res=(res+n)%MOD;for(int i=0; i<len-1; i++) {if(n&(1LL<<i)) {//最高位為1時if (i==0)res=(res+1)%MOD;else{temp1=((3LL<<i)%MOD-1+MOD)%MOD;temp2=quickModPow(2,i-1,MOD);res=(res+(temp1*temp2)%MOD)%MOD;}}}printf("%lld\n", res);}}return 0; }?
總結
以上是生活随笔為你收集整理的Maximum Flow(2017 ACM-ICPC 亚洲区(西安赛区)网络赛 E)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 训练日志 2019.3.20
- 下一篇: 蚂蚁(51Nod-1266)