Exclusive orTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 377 Accepted Submission(s): 159
Problem 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
Sample Output
Author
Xiaoxu Guo (ftiasch)
Source
Recommend
|
公式题解已经给出了,貌似有网站上可以直接搜到那个公式:
if(n<2)
return 0;
if(n%2==0)
return 2*a(n/2)+2*a(n/2-1)+4*(n/2-1);
else return 4*a((n-1)/2)+6*((n-1)/2);
不过这题数据很大,建议用Java写,因为Java里面在记忆化搜索时存数据要方便很多,而因为这题不用记忆化搜索的话,很容易超时,
import java.util.*;
import java.math.BigInteger;
public class Main {
public static HashMap<BigInteger, BigInteger> map = new HashMap<BigInteger, BigInteger>();
public static BigInteger fun(BigInteger x)
{
if(map.containsKey(x))
return map.get(x);
BigInteger temp,next,next2,ans;
temp = BigInteger.valueOf(2);
next = x.divide(temp);
next2 = x.add(BigInteger.ONE.negate());
next2 = next2.divide(temp);
if(x.compareTo(BigInteger.valueOf(2))<0)
return BigInteger.ZERO;
if(x.mod(temp).compareTo(BigInteger.ZERO)==0)
ans = temp.multiply(fun(next)).add(temp.multiply(fun(next.add(BigInteger.ONE.negate())))).add(next.add(BigInteger.ONE.negate()).multiply(BigInteger.valueOf(4)));
else ans = BigInteger.valueOf(4).multiply(fun(next2)).add(BigInteger.valueOf(6).multiply(next2));
map.put(x, ans);
return ans;
}
public static void main(String[] agrs)
{
Scanner cin = new Scanner(System.in);
BigInteger n;
while(cin.hasNext())
{
n = cin.nextBigInteger();
System.out.println(fun(n));
}
cin.close();
}
}
下面是C++大数写的,不过没加记忆化,T了
#include<iostream>
#include<cstdio>
#include<cstring>
#include<time.h>
#include<math.h>
#include<algorithm>
#define MM 1000000000
using namespace std;
struct Bignum{
__int64 dig[60];
int len;
void clean()
{
memset(dig,0,sizeof(dig));
len=1;
}
void print(bool flag=false)
{
int i=len-1;
printf("%I64d",dig[i]);
for(i--;i>=0;i--)
printf("%09I64d",dig[i]);
if(flag)
printf("\n");
}
};
Bignum zero,one;
Bignum add(Bignum a,Bignum b) //大数的加法模版
{
if(b.len>a.len)
a.len=b.len;
for(int i=0;i<a.len;i++)
{
a.dig[i] += b.dig[i];
if(a.dig[i]>=MM)
{
a.dig[i] -= MM;
a.dig[i+1]++;
}
if(a.dig[a.len]>0)
a.len++;
}
return a;
}
Bignum cut(Bignum a,Bignum b) //大数的减法模版,只考虑a大于b的情况
{
for(int i=0;i<a.len;i++)
{
a.dig[i] -= b.dig[i];
if(a.dig[i]<0)
{
a.dig[i] += MM;
a.dig[i+1]--;
}
while(a.len>1&&!a.dig[a.len-1])//
a.len--;
}
return a;
}
Bignum multi(Bignum a,__int64 b) //大数与__int64的乘法模版
{
for(int i=0;i<a.len;i++)
a.dig[i] *= b;
for(int i=0;i<a.len;i++)
if(a.dig[i]>=MM)
{
a.dig[i+1] += a.dig[i]/MM;
a.dig[i] %= MM;
}
while(a.dig[a.len]>0)
{
a.dig[a.len+1] += a.dig[a.len]/MM;
a.dig[a.len] %= MM;
a.len++;
}
return a;
}
Bignum multi(Bignum a,Bignum b)//两个大数的乘法运算(很经典)
{
int i,j;
__int64 d;
Bignum c;c.clean();
c.len=a.len+b.len;
for(i=0;i<a.len;i++)
for(j=0;j<b.len;j++)
{
d=a.dig[i]*b.dig[j];
c.dig[i+j+1] += (d + c.dig[i+j])/MM;
c.dig[i+j] = (d+ c.dig[i+j])%MM;
}
if(!c.dig[c.len-1])//
c.len--;
return c;
}
Bignum division(Bignum a,__int64 b) //大数的除法模版
{
for(int i=a.len-1;i>0;i--)//此循环i不能等于0
{
a.dig[i-1] += a.dig[i]%b*MM;
a.dig[i] /= b;
}
a.dig[0] /= b;
while(a.len>1&&!a.dig[a.len-1])
{
a.len--;
}
return a;
}
int cmp(Bignum a,Bignum b) //比较两个大数的大小
{
if(a.len>b.len)
return 1;
else if(a.len<b.len)
return -1;
for(int i=a.len-1;i>=0;i--)
if(a.dig[i]!=b.dig[i])
return a.dig[i]-b.dig[i];
return 0;
}
Bignum intchange(__int64 s)//将一个__int64类型的树转化成大数
{
Bignum c;
c.clean();
int i=0;
if(!s) return c;
while(s>0)
{
c.dig[i++] = s%MM;
s /= MM;
}
c.len=i;
return c;
}
Bignum charchange(char s[])//将字符串转换成大数
{
Bignum c;c.clean();
int i,j,k=0,L=strlen(s);
__int64 p;
for(i=L-1;i>=0;)
{
p=1;
for(j=0;j<9&&i>=0;j++,i--)
{
c.dig[k] += p*(s[i]-'0');
p *= 10;
}
k++;
}
c.len=k;
return c;
}
__int64 bigmod(Bignum a,__int64 s)//大数取余
{
int i;
__int64 mod=MM%s,ret;
for(i=a.len-1;i>=0;i--)
{
ret = (ret*mod+a.dig[i])%s;
}
return ret;
}
Bignum sove(Bignum x)
{
Bignum temp,next;
temp = intchange(2);
next = division(x,2);
if(cmp(x,temp)<0)
return zero;
if(bigmod(x,2)==0)
return add(multi(temp,add(sove(next),sove(cut(next,one)))),multi(cut(next,one),4));
//return 2*a(n/2)+2*a(n/2-1)+4*(n/2-1);
else return add(multi(sove(division(cut(x,one),2)),4),multi(division(cut(x,one),2),6));
//else return 4*a((n-1)/2)+6*((n-1)/2);
}
int main()
{
char s[550];
Bignum n,ans;
zero.clean();
one.clean();
one.dig[0]++;
while(~scanf("%s",s))
{
n = charchange(s);
ans = sove(n);
ans.print();
cout<<endl;
}
return 0;
}