zoukankan      html  css  js  c++  java
  • [高精度][数学] Jzoj P3771 小Z的烦恼

    Description

    小 Z 最近遇上了大麻烦,他的数学分析挂科了。于是他只好找数分老师求情。

    善良的数分老师答应不挂他,但是要求小 Z 帮助他一起解决一个难题问题是这样的,现在有 n 个标号为 1~n 的球和 m 个盒子,每个球都可以放进且只能放进一个盒子里面,但是要满足如下的规则:

    1.  若把标号为 i 的球放进了第 j 个盒子,那么标号为 2*i 的球一定要在第 j+1 个盒子里面(若 j<m)

    2.  若把标号为 i 的球放进了第 j 个盒子,并且 k*2=i,那么标号为 k 的球一定要在第 j-1 个盒子里面(若 j>1)

    小 Z 的数分老师想要知道,给定了 n 和 m 的时候,第一个盒子最多能放进去多少个球。事实上,他已经推算出了公式,但是需要检验当 n 趋向于无穷大时是否仍然满足这个公式,因此 n 可能会非常大。
     

    Input

    本题包含多组数据,第一行为一个数(T<=20),表示数据组数;以下 T 行,每组数据一行,包括两个数 n 和 m。

    Output

    每组数据输出一行,包括一个数,即第一个盒子最多能放进多少个球。
     

    Sample Input

    2
    10 2
    10 3

    Sample Output

    4
    1
     
     

    Data Constraint

    对于 10%的数据,n<=10^6

    对于 20%的数据,n<=10^9

    对于 30%的数据,m=2

    对于 100%的数据,n<=10^10000,2<=m<=25
     

    Hint

    样例解释:

    (1).{1,3,4,5}, {2,6,8,10}

    (2).{1},{2},{4}

    题解

    • 题目大意:有n个球,m个格子,如果i格子放了x,那么i+1格子一定要放2*x,i-1格子一定要放x/2(整除),问第一个格子里最多有多少个球
    • 可以发现第一个格子的数应该满足
    • 那么我们就可以每次将n除去2^m-1然后统计奇数个数,然后在一直除2^m再统计奇数个数直到n为0
    • 总共的奇数个数就是答案

    代码

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cstring>
     4 #define ll long long
     5 using namespace std;
     6 const ll N=1e4+10,mo=1e11;
     7 ll a[N],ans[N],b[N],n,t,k,len,x,y,z,m,T,num;
     8 char s[N];
     9 void chu(ll x)
    10 {
    11     ll r=0;
    12     for (ll i=a[0];i>=1;i--) a[i]=r*mo+a[i],r=a[i]%x,a[i]/=x;
    13     while (!a[a[0]]&&a[0]) a[0]--;
    14 }
    15 void count()
    16 {
    17     ll r=0;
    18     for (ll i=a[0];i>=1;i--) ans[i]+=(r*mo+a[i])/2,r=a[i]%2;
    19     r=max(ans[0],a[0]-1);
    20     if (ans[r+1]) r++;
    21     for (ll i=1;i<=r;i++) if (ans[i]>=mo) ans[i]-=mo,ans[i+1]++;
    22     if (ans[r+1]) ans[0]=r+1; else if (ans[r]) ans[0]=r; else if (ans[r-1]) ans[0]=r-1;
    23 }
    24 int main()
    25 {
    26     scanf("%lld",&T); 
    27     while (T--)
    28     {
    29         memset(a,0,sizeof(a)),memset(ans,0,sizeof(ans));
    30         scanf("%s%lld",s+1,&m),len=strlen(s+1),k=1,n=1;
    31         for (ll i=len;i>=1;i--)
    32         {
    33             a[n]+=(s[i]-48)*k,k*=10;
    34             if (k==mo) k=1,n++;
    35         }
    36         a[0]=n,chu(1<<(m-1)),n=a[1]%2,count(),ans[1]+=n;
    37         while (a[0]) chu(1<<m),n=a[1]%2,count(),ans[1]+=n;
    38         if (!ans[0]) ans[0]=1;
    39         printf("%lld",ans[ans[0]]);
    40         for (ll i=ans[0]-1;i>=1;i--)
    41         {
    42             ll k=mo/10;
    43             while (ans[i]<k&&k>0) printf("0"),k/=10;
    44             printf("%lld",ans[i]);
    45         }
    46         printf("
    ");
    47     }
    48 }
  • 相关阅读:
    toggleClass
    CSS实现文字旋转/实现角标
    vs直接IP访问运行项目
    移除页面蓝色层
    JS防止页面被其他网站iframe使用方法
    JS执行保存在数据库中的JS代码
    JavaScript中函数是不能重载原因
    jquery 根据文内内容获取dom
    IIS无法加载字体文件(*.woff,*.svg)的解决办法
    MySQL 的 RowNum 实现
  • 原文地址:https://www.cnblogs.com/Comfortable/p/10292085.html
Copyright © 2011-2022 走看看