题目连接 : http://acm.hdu.edu.cn/showproblem.php?pid=4933
题意 : 自己看吧,还是很容易理解的,就一个公式而已。
方法 : 比赛的时候想到两次数位DP:先对所有的数进行一次mod9 的数位DP,再得出的答案x为新的mod,再进行一次mod,后来写着写着发现似乎有点问题,对于answer = 0要特判,然后没想到好的方法,比赛就结束了。
赛后用java写了一发大数过的,对于题解中用多个大质数去判这种神奇的作法只能意会下了 , 貌似rand() 也行?
1 import java.io.*; 2 import java.util.*; 3 import java.math.*; 4 5 public class Main { 6 7 /** 8 * @param args 9 */ 10 public static class Pair { 11 BigInteger cnt, sum; 12 } 13 14 public static BigInteger sum[][] = new BigInteger[105][3]; 15 public static BigInteger cnt[][] = new BigInteger[105][3]; 16 public static int bit[] = new int[105]; 17 public static boolean vis[][] = new boolean[105][3]; 18 19 public static Pair dfs(int len, int dis, boolean fp) { 20 //System.out.println(len + " " + s + " " + dis + " " + fp); 21 Pair ret = new Pair(); 22 if (len == 0) { 23 ret.cnt = BigInteger.ONE; ret.sum = BigInteger.ZERO; 24 return ret; 25 } 26 if (fp == false && vis[len][dis] == true) { 27 ret.cnt = cnt[len][dis]; 28 ret.sum = sum[len][dis]; 29 return ret; 30 } 31 int Max; 32 BigInteger Sum = BigInteger.ZERO; 33 BigInteger Cnt = BigInteger.ZERO; 34 if (fp == true) Max = bit[len]; 35 else Max = 9; 36 //System.out.println("Max = " + Max); 37 for (int i = 0; i <= Max; i++) { 38 if (i > 0) { 39 if (dis == 0 || dis == 1) { 40 ret = dfs(len-1, 2, fp==true&&i==Max); 41 Cnt = Cnt.add(ret.cnt); Sum = Sum.add(ret.sum); 42 Sum = Sum.add(ret.cnt.multiply(BigInteger.valueOf(i))); 43 }else { 44 ret = dfs(len-1, 3-dis, fp==true&&i==Max); 45 Cnt = Cnt.add(ret.cnt); Sum = Sum.add(ret.sum); 46 Sum = Sum.subtract(ret.cnt.multiply(BigInteger.valueOf(i))); 47 } 48 }else { 49 if (dis == 0) { 50 ret = dfs(len-1, dis, fp==true&&i==Max); 51 Cnt = Cnt.add(ret.cnt); Sum = Sum.add(ret.sum); 52 }else { 53 ret = dfs(len-1, 3-dis, fp==true&&i==Max); 54 Cnt = Cnt.add(ret.cnt); Sum = Sum.add(ret.sum); 55 } 56 } 57 } 58 if (fp == false) { 59 vis[len][dis] = true; 60 sum[len][dis] = Sum; 61 cnt[len][dis] = Cnt; 62 } 63 ret.cnt = Cnt; ret.sum = Sum; 64 return ret; 65 } 66 public static BigInteger solve(BigInteger x) { 67 if (x.equals(BigInteger.valueOf(-1))) return BigInteger.ZERO; 68 String tmp = String.valueOf(x); 69 for (int i = 0; i < tmp.length(); i++) { 70 bit[i+1] = tmp.charAt(tmp.length() - i - 1) - '0'; 71 } 72 return dfs(tmp.length(), 0, true).sum; 73 } 74 public static void main(String[] args) { 75 // TODO Auto-generated method stub 76 Scanner cin = new Scanner(System.in); 77 int T = cin.nextInt(); 78 for (int cas = 1; cas <= T; cas++) { 79 BigInteger L, R; 80 L = cin.nextBigInteger(); 81 R = cin.nextBigInteger(); 82 BigInteger answer = solve(R).subtract(solve(L.subtract(BigInteger.ONE))); 83 BigInteger Mod = answer; 84 if (Mod.compareTo(BigInteger.ZERO) == 0) { 85 Mod = BigInteger.ZERO; 86 }else { 87 Mod = Mod.mod(BigInteger.valueOf(9)); 88 if (Mod.compareTo(BigInteger.ZERO) <= 0) Mod = Mod.add(BigInteger.valueOf(9)); 89 } 90 if (Mod.equals(BigInteger.ZERO)) { 91 System.out.println("Error!"); 92 }else { 93 answer = answer.mod(Mod); 94 if (answer.compareTo(BigInteger.ZERO) < 0) answer = answer.add(Mod); 95 System.out.println(answer); 96 } 97 } 98 } 99 100 }
为什么java不能重载运算符呢!!!一个a = a.add(b) 写成 a.add(b)害的我差错查了1个小时啊! T T