Codeforces Gym 100431B Binary Search 搜索+组合数学+高精度

原题链接:http://codeforces.com/gym/100431/attachments/download/2421/20092010-winter-petrozavodsk-camp-andrew-stankevich-contest-37-asc-37-en.pdf

题意

给你一个n,问你有多少a和x满足:x在a中二分会返回true,其中a的长度是n

题解

考虑到二分的过程不是向左就是向右,所以可以暴力搜索搞到若干序列,这些序列都是由向左或者向右组成的。枚举x,设向左的有i个,向右的有j个,这样的序列有cnt[i][j]个,表明整个序列,确定有i个数小于等于x,有j个数大于x,那么答案就是cnt[i][j] * (x ^ (i - 1)) * ((n - x) ^ j) * (n ^ (n - i - j)),当x等于0是需要特判一下。代码是队友用java写的。

代码

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.*;


public class Main {
    static int n;
    static BigInteger ans = new BigInteger("0");
    static int xs[][] = new int[15][15]; 
    static BigInteger tmp[] = new BigInteger[1010];
    public Main() throws FileNotFoundException{
        Scanner cin = new Scanner(new File("binary.in"));
        PrintWriter cout = new PrintWriter(new File("binary.out"));
        n = cin.nextInt();
        tmp[0] = new BigInteger("1");
        tmp[1] = new BigInteger(Integer.toString(n));
        for(int i=2;i<=1000;i++) tmp[i] = tmp[i-1].multiply(tmp[1]);
        if(n == 1){
            cout.println("1");
        }
        else{
            dfs(0,0,0,n);
            for(int i=0;i<13;i++) for(int j=0;j<13;j++) if(xs[i][j] != 0){
                if(i == 0){
                    BigInteger tmp3 = tmp[n - i - j - 1];
                    for(int k=1;k<=n;k++){
                        BigInteger tmp1 = new BigInteger(Integer.toString(k - 1));
                        tmp1 = tmp1.pow(j);
                        ans = ans.add(tmp1.multiply(tmp3).multiply(new BigInteger(Integer.toString(xs[i][j]))));
                    }
                }
                else{
                    for(int k=1;k<=n;k++){
                        BigInteger tmp1 = new BigInteger(Integer.toString(n-k));
                        tmp1 = tmp1.pow(j);
                        if(j == 0 && n == k) tmp1 = new BigInteger("1");
                        BigInteger tmp2 = new BigInteger(Integer.toString(k));
                        tmp2 = tmp2.pow(i-1);
                        BigInteger tmp3 = tmp[n-i-j];
                        ans = ans.add(tmp1.multiply(tmp2.multiply(tmp3)).multiply(new BigInteger(Integer.toString(xs[i][j]))));
                    }
                }
            }
            cout.println(ans);
        }
        cin.close();
        cout.close();
    }
    
    void dfs(int x,int y,int l,int r){
        if(l + 1 >= r){
            xs[x][y]++;
            return ;
        }
        int mid = (l + r) / 2;
        dfs(x+1,y,mid,r);
        dfs(x,y+1,l,mid);
    }
    
    public static void main(String[] args) throws FileNotFoundException {
        new Main();
    }
}
原文地址:https://www.cnblogs.com/HarryGuo2012/p/4738141.html