Maximum Flow - 2017 ACM-ICPC 亚洲区(西安赛区)网络赛
2017-09-16 23:01
363 查看
Given a directed graph with nn nodes,
labeled 0,1,
\cdots, n-10,1,⋯,n−1.
For each <i,
j><i,j> satisfies 0
\le i < j < n0≤i<j<n,
there exists an edge from the i-th node to the j-th node, the capacity of which is ii xor jj.
Find the maximum flow network from the 0-th node to the (n-1)-th node, modulo 10000000071000000007.
In each test case, one integer in a line denotes n(2
\le n \le 10^{18})n(2≤n≤1018
4000
).
each test case.
2017
ACM-ICPC 亚洲区(西安赛区)网络赛
设点的最大编号为n,则n二进制最高位是1,设另一个数m对应的二进制位是0,则n^m>0^m=m,0到m的所有流量必定可以到达汇点n.这一部分的贡献是2^x*(2^x-1)/2, 2^x是小于等于n的最大的2的次方。
对于二进制最高位和n相同的数字k,可以转达的最大流量就是n^k.因为n^k<0^k=k.那么我们只要计算这一部分的异或和就可以了。
那么异或打个表找规律,发现把n转为二进制之后,除去最高位,每一位对答案的贡献是1,5,22,92......,这一串数字可以通过递推:
sum=q=1
for ()
sum=sum*2-q;
q=q*4;
sum+=q;
得到。
之后就直接上java的BigInteger.
package main;
import java.math.BigInteger;
import java.util.Scanner;
public class Fuck {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
BigInteger n;
BigInteger p[]=new BigInteger [105];
BigInteger a[]=new BigInteger [105];
BigInteger b[]=new BigInteger [105];
BigInteger c[]=new BigInteger [105];
BigInteger q=BigInteger.ONE,sum=BigInteger.ONE,m=BigInteger.valueOf(1000000007);
int i;
p[0]=BigInteger.ZERO;a[0]=BigInteger.ONE;b[0]=BigInteger.ONE;
for (i=1;i<=64;i++) {
p[i]=sum;
sum=sum.add(sum).subtract(q);
q=q.multiply(BigInteger.valueOf(4));
sum=sum.add(q);
}
for (i=1;i<=61;i++) {
a[i]=a[i-1].multiply(BigInteger.valueOf(2));
b[i]=a[i].multiply(a[i].subtract(BigInteger.ONE)).divide(BigInteger.valueOf(2));
}
while (in.hasNextBigInteger()) {
n=in.nextBigInteger();
if (n.compareTo(BigInteger.valueOf(2))==0) {
System.out.println("1");
continue;
}
n=n.subtract(BigInteger.ONE);
int cnt=1;
while (n.compareTo(a[cnt+1])>=0) cnt++;
BigInteger ans=b[cnt];
ans=ans.add(n);
n=n.subtract(a[cnt]);
cnt=0;
while (n.compareTo(BigInteger.ZERO)!=0) {
cnt++;
if (n.mod(BigInteger.valueOf(2)).compareTo(BigInteger.ONE)==0) ans=ans.add(p[cnt]);
n=n.divide(BigInteger.valueOf(2));
}
ans=ans.mod(m);
System.out.println(ans);
}
}
}
}
labeled 0,1,
\cdots, n-10,1,⋯,n−1.
For each <i,
j><i,j> satisfies 0
\le i < j < n0≤i<j<n,
there exists an edge from the i-th node to the j-th node, the capacity of which is ii xor jj.
Find the maximum flow network from the 0-th node to the (n-1)-th node, modulo 10000000071000000007.
Input Format
Multiple test cases (no more than 1000010000).In each test case, one integer in a line denotes n(2
\le n \le 10^{18})n(2≤n≤1018
4000
).
Output Format
Output the maximum flow modulo 10000000071000000007 foreach test case.
样例输入
2
样例输出
1
题目来源
2017ACM-ICPC 亚洲区(西安赛区)网络赛
设点的最大编号为n,则n二进制最高位是1,设另一个数m对应的二进制位是0,则n^m>0^m=m,0到m的所有流量必定可以到达汇点n.这一部分的贡献是2^x*(2^x-1)/2, 2^x是小于等于n的最大的2的次方。
对于二进制最高位和n相同的数字k,可以转达的最大流量就是n^k.因为n^k<0^k=k.那么我们只要计算这一部分的异或和就可以了。
那么异或打个表找规律,发现把n转为二进制之后,除去最高位,每一位对答案的贡献是1,5,22,92......,这一串数字可以通过递推:
sum=q=1
for ()
sum=sum*2-q;
q=q*4;
sum+=q;
得到。
之后就直接上java的BigInteger.
package main;
import java.math.BigInteger;
import java.util.Scanner;
public class Fuck {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
BigInteger n;
BigInteger p[]=new BigInteger [105];
BigInteger a[]=new BigInteger [105];
BigInteger b[]=new BigInteger [105];
BigInteger c[]=new BigInteger [105];
BigInteger q=BigInteger.ONE,sum=BigInteger.ONE,m=BigInteger.valueOf(1000000007);
int i;
p[0]=BigInteger.ZERO;a[0]=BigInteger.ONE;b[0]=BigInteger.ONE;
for (i=1;i<=64;i++) {
p[i]=sum;
sum=sum.add(sum).subtract(q);
q=q.multiply(BigInteger.valueOf(4));
sum=sum.add(q);
}
for (i=1;i<=61;i++) {
a[i]=a[i-1].multiply(BigInteger.valueOf(2));
b[i]=a[i].multiply(a[i].subtract(BigInteger.ONE)).divide(BigInteger.valueOf(2));
}
while (in.hasNextBigInteger()) {
n=in.nextBigInteger();
if (n.compareTo(BigInteger.valueOf(2))==0) {
System.out.println("1");
continue;
}
n=n.subtract(BigInteger.ONE);
int cnt=1;
while (n.compareTo(a[cnt+1])>=0) cnt++;
BigInteger ans=b[cnt];
ans=ans.add(n);
n=n.subtract(a[cnt]);
cnt=0;
while (n.compareTo(BigInteger.ZERO)!=0) {
cnt++;
if (n.mod(BigInteger.valueOf(2)).compareTo(BigInteger.ONE)==0) ans=ans.add(p[cnt]);
n=n.divide(BigInteger.valueOf(2));
}
ans=ans.mod(m);
System.out.println(ans);
}
}
}
}
相关文章推荐
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 Maximum Flow
- 计蒜客 17118 Maximum Flow(2017 ACM-ICPC 亚洲区(西安赛区)网络赛 E)
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 Xor
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 C
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 E. Maximum Flow(最大流/规律)
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 F. Trig Function cos(nx)
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛: F. Trig Function
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 F. Trig Function cos(nx)
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 Coin(组合数)
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 E.Maximum Flow【规律】
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 B题 coin
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛: B. Coin
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 I. Barty's Computer(哈希||字典树)
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 B. Coin
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 xor (根号分治)
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 B. Coin
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 B Coin(逆元,费马小定理)
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 B.Coin(数学推公式)
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 B. Coin