• 51Nod1799 二分答案


    Problem

    lyk最近在研究二分答案类的问题。

    对于一个有n个互不相同的数且从小到大的正整数数列a(其中最大值不超过n),若要找一个在a中出现过的数字m,一个正确的二分程序是这样子的:

    '''
    l=1; r=n; mid=(l+r)/2;
    while (l<=r)
    {
    if (a[mid]<=m)
    l=mid+1;
    else
    r=mid-1;

    mid=(l+r)/2;
    

    }
    '''

    最终a[r]一定等于m。

    但是这个和谐的程序被熊孩子打乱了。

    熊孩子在一开始就将a数组打乱顺序。(共有n!种可能)

    lyk想知道最终r=k的期望。

    由于小数点非常麻烦,所以你只需输出将答案乘以n!后对1000000007取模就可以了。

    在样例中,共有2个数,被熊孩子打乱后的数列共有两种可能(1,2)或者(2,1),其中(1,2)经过上述操作后r=1,(2,1)经过上述操作后r=0。r=k的期望为0.5,0.5*2!=1,所以输出1。

    Solution

    模拟二分找到k,记录关键节点,计算排列,非关键节点阶乘。

    Code

    #include<stdio.h>
    #include<set>
    #include<iostream>
    #include<stack>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<map>
    #include<queue>
    #include<algorithm>
    typedef long long ll;
    typedef long double ld;
    typedef double db;
    #define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    using namespace std;
    const int mod=1e9+7;
    inline int mo(ll a,int p){
        return a>=p?a%p:a;
    }
    inline int rd() {
        int x = 0, f = 1;
        char ch;
        while (ch < '0' || ch > '9') {
            if (ch == '-')f = -1;
            ch = getchar();
        }
        while (ch >= '0' && ch <= '9') {
            x = x * 10 + ch - '0';
            ch = getchar();
        }
        return f * x;
    }
    inline ll gcd(ll x, ll y){
        return y==0?x:gcd(y,x%y);
    }
    inline ll speed(ll a,ll b){
        ll cur=a,anss=1;
        while(b){
            if(b&1) anss=anss*cur;
            cur=cur*cur;
            b>>=1;
        }
        return anss;
    }
    const int MAXN=1e5;
    bool ipr[MAXN+20];
    int cnt,pri[MAXN/5];
    void prime(){//埃式筛法
        int N=sqrt(MAXN)+0.5,mul;
        memset(ipr,true,sizeof(ipr));
        ipr[1]=false;
        for(int i=2;i<=N;i++){
            if(ipr[i]==true){
                i==2?mul=1:mul=2;
                for(int j=i*i;j<=MAXN;j+=i*mul){
                    ipr[j]=false;
                }
            }
        }
        for(int i=2;i<=MAXN;i++){
            if(ipr[i]==true){
                pri[++cnt]=i;
            }
        }
    }
    int f[120]={1,682498929,491101308,76479948,723816384,67347853,27368307,625544428,199888908,888050723,
                927880474,281863274,661224977,623534362,970055531,261384175,195888993,66404266,547665832,109838563,
                933245637,724691727,368925948,268838846,136026497,112390913,135498044,217544623,419363534,500780548,
                668123525,128487469,30977140,522049725,309058615,386027524,189239124,148528617,940567523,917084264,
                429277690,996164327,358655417,568392357,780072518,462639908,275105629,909210595,99199382,703397904,
                733333339,97830135,608823837,256141983,141827977,696628828,637939935,811575797,848924691,131772368,
                724464507,272814771,326159309,456152084,903466878,92255682,769795511,373745190,606241871,825871994,
                957939114,435887178,852304035,663307737,375297772,217598709,624148346,671734977,624500515,748510389,
                203191898,423951674,629786193,672850561,814362881,823845496,116667533,256473217,627655552,245795606,
                586445753,172114298,193781724,778983779,83868974,315103615,965785236,492741665,377329025,847549272,
                698611116};
    const int con=1e7;
    int n,m,k;
    ll ans=1;
    ll fun(ll x){
        ll ret=f[x/con];
        ll t=x/con;
        for(int i=t*con+1;i<=x;i++){
            ret=mo(ret*i,mod);
        }
        return ret;
    }
    int main(){
        //io_opt;
        scanf("%d%d%d",&n,&m,&k);
        int a=0,b=0;
        int l=1,r=n,mid=(l+r)/2;
        while (l<=r)
        {
            if (mid<=k)
                l=mid+1,a++;
            else
                r=mid-1,b++;
    
            mid=(l+r)/2;
        }
        for(int i=m;i>=m-a+1;i--){
            ans=mo(ans*i,mod);
        }
        for(int i=n-m;i>=n-m-b+1;i--){
            ans=mo(ans*i,mod);
        }
        ans=ans*fun(n-a-b)%mod;
        printf("%lld
    ",ans);
        return 0;
    }
    
    
  • 相关阅读:
    学算法的那些年,吴师兄接触的网站、软件、视频、书籍大揭秘
    阮一峰:CSS Modules 用法教程
    截取url参数
    在dotnet core实现类似crontab的定时任务
    开源一个基于dotnet standard的轻量级的ORM框架-Light.Data
    ABP Vnext使用mysql数据库
    实现ElementUI Dialog宽度响应式变化
    使用Vue Baidu Map对百度地图实现输入框搜索定位
    使用Docker搭建HttpRunnerManager环境
    SpringBoot集成spring aop开发
  • 原文地址:https://www.cnblogs.com/sz-wcc/p/13187978.html
Copyright © 2020-2023  润新知