zoukankan      html  css  js  c++  java
  • HDU 6093

    JAVA+大数搞了一遍- -

    不是很麻烦- -

    /*
    HDU 6093 - Rikka with Number [ 进制转换,康托展开,大数 ]  |  2017 Multi-University Training Contest 5
    题意:
    	求L,R之间的好数的个数,好数要求在某个d(>=2)进制下数位是0到d-1的
    分析:
    	d 进制下好数的个数为 d!-(d-1)! ,且满足 d^(d-1) <= K <= d^d
    	可知 若 N > d^d 则 1-N 包含前 d-1 个进制的所有好数
    	寻找零界 d 可以二分,将 N 和 d^d 比大小
    	
    	计算临界的 d 进制的好数,用类似康托展开的过程
    	即 对于 (x0, x1, x2...xn),转化成 
    	首位小于x0的所有排列+ 首位等于x0第二位小于x1的所有排列+....
    	
    */
    import java.math.BigInteger;
    import java.util.Scanner;
    public class Main {
    	static Scanner cin = new Scanner(System.in);
    	static long MOD = 998244353;
    	static BigInteger a[] = new BigInteger[2000];
    	static long F[] = new long[2000];
    	static BigInteger bb;
    	static String s;
    	static int [] b = new int[5005];
    	static int [] c = new int[5005];
    	static int lc, lb;
    	static void init() {
    		F[0] = 1;
    		for (int i = 1; i < 2000; i++) F[i] = F[i-1] * i % MOD;
    		for (int i = 1; i < 2000; i++) a[i] = BigInteger.valueOf(i).pow(i);	
    	}
    	static int BinaryFind(){
    		int l = 2, r = 1999, mid = 0;
    		while (l <= r) {
    			mid = (l+r)/2;
    			if (bb.compareTo(a[mid]) >= 0) l = mid+1;
    			else r = mid-1;
    		}
    		return l;
    	}
    	static void change(int m) {
    		lc = 0;
    		while (lb > -0) {
    			int x = 0;
    			for (int i = lb-1; i >= 0; i--) {
    				x = x*10 + b[i];
    				b[i] = x/m;
    				x %= m;
    			}
    			c[lc++] = x; while (lb > 0 && b[lb-1] == 0) lb--;
    		}
    	}
    	static int[] vis = new int[5005];
    	static long solve(){
    		int m = BinaryFind();
    		change(m);
    		long ans = F[m-1] - F[1];
    		if (m > lc) return ans;
    		for (int i = 0; i < m; i++) vis[i] = 0;
    		for (int i = 1; i < c[lc-1]; i++) 
    			if (vis[i] == 0)
    				ans = (ans + F[lc-1]) % MOD;
    		vis[c[lc-1]] = 1;
    		for (int i = lc-2; i >= 0; i--)
    		{
    			for (int j = 0; j < c[i]; j++)
    				if (vis[j] == 0)
    					ans = (ans + F[i]) % MOD;
    			if (vis[c[i]] == 1) break;
    			vis[c[i]] = 1;
    			if (i == 0) ans = (ans + 1) % MOD;
    		}
    		return ans;
    	}
    	public static void main(String[] args) {
    		init(); 
    		int t = cin.nextInt();
    		while ((t--) != 0) {		
    			bb = cin.nextBigInteger();
    			s = bb.toString();
    			lb = s.length();
    			for (int i = 0; i < lb; i++) {
    				b[i] = (int)(s.charAt(lb-1-i) - '0');
    			}
    			b[0]--;
    			for (int i = 0; i < lb; i++) {
    				if (b[i] < 0) {
    					b[i] += 10; b[i+1]--;
    				}
    				else break;
    			}
    			while (lb > 0 && b[lb-1] == 0) lb--;
    			long ans = solve();
    			bb = cin.nextBigInteger();
    			s = bb.toString();
    			lb = s.length();
    			for (int i = 0; i < lb; i++) {
    				b[i] = (int)(s.charAt(lb-1-i) - '0');
    			}
    			ans = (MOD + solve() - ans) % MOD;
    			System.out.println(ans);
    		}
    	}
    }
    

      

  • 相关阅读:
    ambari之hbase数据迁移
    elasticsearch之python备份
    python之rabbitMQ篇
    python协程与异步I/O
    Python进程、线程、协程
    paramiko模块使用
    HTTP网络协议(四)
    HTTP网络协议(三)
    HTTP网络协议(二)
    HTTP网络协议(一)
  • 原文地址:https://www.cnblogs.com/nicetomeetu/p/7325581.html
Copyright © 2011-2022 走看看