您的位置:首页 > 其它

HDU 4919 Exclusive or (数论 or 打表找规律)

2016-07-27 17:34 471 查看

Exclusive or

题目链接:

http://acm.hust.edu.cn/vjudge/contest/121336#problem/J

Description

Given n, find the value of



Note: ♁ denotes bitwise exclusive-or.

Input

The input consists of several tests. For each tests:

A single integer n (2≤n<10^500).

Output

For each tests:

A single integer, the value of the sum.

Sample Input

3

4

Sample Output

6

4

题意:

求如题所示的和,n的范围是1e500.

题解:

数据这么大肯定要找规律.

先尝试打出前100个数的表,然后找规律....(弱鸡并不能找出来)

先安利一个网站(http://oeis.org/)这是一个在线整数数列查询网站.

搜一下果然有:(http://oeis.org/A006582)

公式为:a(0)=a(1)=0, a(2n) = 2a(n)+2a(n-1)+4n-4, a(2n+1) = 4a(n)+6n.

由于是个递归公式,可以用dfs来计算,用map去重后应该是O(lgn).

一开始用cpp的大数模版一直出现各种问题(版不太熟悉),干脆复习一下java语法.

网上找到一份题解有推导过程:



代码:

import java.math.BigInteger;
import java.util.HashMap;
import java.util.Scanner;

public class Main {
public static HashMap<BigInteger, BigInteger> myMap = new HashMap<BigInteger,BigInteger>();
public static BigInteger [] num = new BigInteger[10];

public static BigInteger dfs(BigInteger x) {
if(x == num[0] || x== num[1]) return num[0];
if(myMap.containsKey(x))return myMap.get(x);
if(x.mod(num[2]) == num[0]) {
BigInteger n = x.divide(num[2]);
BigInteger tmp = num[2].multiply(dfs(n).add(dfs(n.subtract(num[1])))).add(num[4].multiply(n.subtract(num[1])));
myMap.put(x, tmp);
return tmp;
} else {
BigInteger n = (x.subtract(num[1])).divide(num[2]);
BigInteger tmp = num[4].multiply(dfs(n)).add(num[6].multiply(n));
myMap.put(x, tmp);
return tmp;
}
}

public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);

for(int i=0; i<10; i++) {
num[i] = BigInteger.valueOf(i);
}

while(scanner.hasNext()){
myMap.clear();
BigInteger n = scanner.nextBigInteger();
BigInteger ans = dfs(n);

System.out.println(ans);
}

scanner.close();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: