[JAVA]HDU 4919 Exclusive or

题意很简单, 就是给个n, 算下面这个式子的值.

$sumlimits_{i=1}^{n-1} i otimes (n-i)$

重点是n的范围:2≤n<10500

比赛的时候 OEIS一下得到了一个公式:

$a_0=a_1=a_2=0$;

n为偶数 : $2 imes a_{frac{n}{2}}+2 imes a_{frac{n}{2}-1}+4 imes (frac{n}{2}-1) $

n为奇数 : $4 imes a_{frac{n-1}{2}}+6 imesfrac{n-1}{2}$

然后勇敢的打了一发暴力...想也知道肯定TLE...

之后 学到了一种机智的按位算的方法

  1 import java.io.*;
  2 import java.util.*;
  3 import java.math.*;
  4 
  5 public class Main
  6 {
  7     static BigInteger yi=BigInteger.ONE;
  8     static BigInteger er=BigInteger.valueOf(2);
  9     static BigInteger li=BigInteger.ZERO;
 10     public static void main(String[] args)
 11     {
 12         InputReader in = new InputReader();
 13         PrintWriter out = new PrintWriter(System.out);
 14         BigInteger []bit=new BigInteger[2005];
 15         bit[0]=yi;
 16         for(int i=1; i<=2000; i++)
 17             bit[i]=bit[i-1].multiply(er);
 18         while(in.hasNext())
 19         {
 20             BigInteger n=new BigInteger(in.next());
 21             int []wei=new int[2005];
 22             int d=0;
 23             BigInteger []a=new BigInteger[2005];
 24             BigInteger []b=new BigInteger[2005];
 25             BigInteger tmp=n;
 26             while(tmp.compareTo(li)!=0)
 27             {
 28                 if(tmp.mod(er).equals(li))
 29                     wei[d++]=0;
 30                 else 
 31                     wei[d++]=1;
 32                 tmp=tmp.divide(er);
 33             }
 34             BigInteger sum=li, ji=yi;
 35             for(int i=0; i<d; i++)
 36             {
 37                 if(wei[i]>0)
 38                     sum=sum.add(ji);
 39                 ji=ji.multiply(er);
 40                 a[i+1]=sum;
 41             }
 42             sum=li;
 43             for(int i=d; i>=0; i--)
 44             {
 45                 sum=sum.multiply(er).add(BigInteger.valueOf(wei[i]));
 46                 b[i+1]=sum;
 47             }
 48             a[0]=li;
 49             BigInteger ans=li;
 50             for(int i=0; i<d; i++)
 51                 if(wei[i]==0)
 52                 {
 53                     BigInteger an=(bit[i].subtract(a[i]).subtract(yi)).multiply(b[i+2]).multiply(bit[i]);
 54                     ans=ans.add(an).add(an);
 55                 }
 56                 else 
 57                 {
 58                     BigInteger an=((a[i].add(yi)).multiply(b[i+2].add(yi)).subtract(yi)).multiply(bit[i]);
 59                     ans=ans.add(an).add(an);
 60                 }
 61             out.println(ans);
 62         }
 63         out.close();
 64     }
 65 }
 66 class InputReader
 67 {
 68     BufferedReader buf;
 69     StringTokenizer tok;
 70     InputReader()
 71     {
 72         buf = new BufferedReader(new InputStreamReader(System.in));
 73     }
 74     boolean hasNext()
 75     {
 76         while(tok == null || !tok.hasMoreElements()) 
 77         {
 78             try
 79             {
 80                 tok = new StringTokenizer(buf.readLine());
 81             } 
 82             catch(Exception e) 
 83             {
 84                 return false;
 85             }
 86         }
 87         return true;
 88     }
 89     String next()
 90     {
 91         if(hasNext()) 
 92             return tok.nextToken();
 93         return null;
 94     }
 95     int nextInt()
 96     {
 97         return Integer.parseInt(next());
 98     }
 99     long nextLong()
100     {
101         return Long.parseLong(next());
102     }
103     double nextDouble()
104     {
105         return Double.parseDouble(next());
106     }
107     BigInteger nextBigInteger()
108     {
109         return new BigInteger(next());
110     }
111     BigDecimal nextBigDecimal()
112     {
113         return new BigDecimal(next());
114     }
115 }
HDOJ 4919

再之后 学习了一下map的记忆化搜索

 1 import java.io.*;
 2 import java.util.*;
 3 import java.math.*;
 4 
 5 public class Main
 6 {
 7     static BigInteger yi=BigInteger.ONE;
 8     static BigInteger er=BigInteger.valueOf(2);
 9     static BigInteger li=BigInteger.ZERO;
10     static BigInteger sa=BigInteger.valueOf(3);
11     static BigInteger si=BigInteger.valueOf(4);
12     static BigInteger liu=BigInteger.valueOf(6);
13     static HashMap<BigInteger, BigInteger> a=new HashMap<BigInteger, BigInteger>();
14     public static BigInteger dfs(BigInteger n)
15     {
16         if(a.containsKey(n))
17             return a.get(n);
18         BigInteger m;
19         if(n.mod(er).equals(li))
20         {
21             BigInteger aa=n.divide(er);
22             BigInteger bb=dfs(aa).multiply(er);
23             BigInteger cc=dfs(aa.subtract(yi)).multiply(er);
24             m=(aa.subtract(yi)).multiply(si).add(bb).add(cc);
25         }
26         else
27         {
28             BigInteger aa=(n.subtract(yi)).divide(er);
29             m=dfs(aa).multiply(si).add(aa.multiply(liu));
30         }
31         a.put(n, m);
32         return m;
33     }
34     public static void main(String[] args)
35     {
36         InputReader in = new InputReader();
37         PrintWriter out = new PrintWriter(System.out);
38         a.put(li, li);
39         a.put(yi, li);
40         a.put(er, li);
41         while(in.hasNext())
42         {
43             BigInteger n=new BigInteger(in.next());
44             out.println(dfs(n));
45         }
46         out.close();
47     }
48 }
49 class InputReader
50 {
51     BufferedReader buf;
52     StringTokenizer tok;
53     InputReader()
54     {
55         buf = new BufferedReader(new InputStreamReader(System.in));
56     }
57     boolean hasNext()
58     {
59         while(tok == null || !tok.hasMoreElements()) 
60         {
61             try
62             {
63                 tok = new StringTokenizer(buf.readLine());
64             } 
65             catch(Exception e) 
66             {
67                 return false;
68             }
69         }
70         return true;
71     }
72     String next()
73     {
74         if(hasNext()) 
75             return tok.nextToken();
76         return null;
77     }
78     int nextInt()
79     {
80         return Integer.parseInt(next());
81     }
82     long nextLong()
83     {
84         return Long.parseLong(next());
85     }
86     double nextDouble()
87     {
88         return Double.parseDouble(next());
89     }
90     BigInteger nextBigInteger()
91     {
92         return new BigInteger(next());
93     }
94     BigDecimal nextBigDecimal()
95     {
96         return new BigDecimal(next());
97     }
98 }
HDOJ 4919
原文地址:https://www.cnblogs.com/Empress/p/4000842.html