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

$\sum\limits_{i=1}^{n-1} i \otimes (n-i)$

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

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

$a_0=a_1=a_2=0$;

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

n为奇数 : $4\times a_{\frac{n-1}{2}}+6\times\frac{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

相关文章: