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

65 篇文章 0 订阅
43 篇文章 0 订阅

Given a directed graph with nnn nodes, labeled 0,1,⋯,n−10,1, \cdots, n-10,1,,n1.

For each <i,j><i, j><i,j> satisfies 0≤i<j<n0 \le i < j < n0i<j<n, there exists an edge from the i-th node to the j-th node, the capacity of which is iii xor jjj.

Find the maximum flow network from the 0-th node to the (n-1)-th node, modulo 100000000710000000071000000007.

Input Format

Multiple test cases (no more than 100001000010000).

In each test case, one integer in a line denotes n(2≤n≤1018)n(2 \le n \le 10^{18})n(2n1018).

Output Format

Output the maximum flow modulo 100000000710000000071000000007 for each test case.

样例输入
2
样例输出
1


分析:不是很懂各位打表找规律选手,最优方案应该是0连向每一个点,然后每一个点再直接连向最后一个点,考虑此时的最大流,设n-1的最高位为2^k,则1到2^k-1 异或上n-1一定是大于自己的,所以这部分流量可以直接算一个等差数列和求出来,然后考虑大于2^k的点,这些点能贡献给n-1的流量一定是其编号和n-1的异或,我们去掉一定会被异或掉的最高位k后就变成了sigma(i ^ n) 其中 i <= n,这部分和手动推一下也可以直接计算。


#include <bits/stdc++.h>
const int MOD = 1000000007;
using namespace std;
typedef unsigned long long ll;
ll n;
ll ksm(ll x,ll y)
{
	ll cnt = 1;
	while(y)
	{
		if(y & 1) cnt = cnt * x % MOD;
		x = x * x % MOD;
		y>>=1;
	}
	return cnt;
}
int main()
{
	while(scanf("%llu",&n) != EOF)
	{
		n--;
		ll ans = 0;
		bool flag = false;
		for(int i = 63;i >= 0;i--)
		{
			if( (1ll<<i) & n)
			{
				if(!flag)
				{
					flag = true;
					ans = (ans + ((1ll<<(i-1)) % MOD)*( ((1ll<<i) - 1) % MOD) % MOD) % MOD; 
				}
				else 
					ans = (ans + ksm(2,2*i) + ((1ll<<(i-1)) % MOD) * ( ((1ll<<i) - 1) % MOD) % MOD) % MOD;
			}
		}
		cout<<(ans+n) % MOD<<endl;
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值