【SPOJ】1182 Sorted bit sequence

【算法】数位DP

【题解】动态规划

写了预处理函数却忘了调用是一种怎样的体验?

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[35][35];
void init()
{
    f[0][0]=1;
    for(int i=1;i<=31;i++)
     {
         f[i][0]=1;
         for(int j=1;j<=i;j++)f[i][j]=f[i-1][j]+f[i-1][j-1];
     }
}
int find(int x,int k)
{
    int tot=0,ans=0;
    for(int i=31;i>0;i--)
     {
         if((1<<i)&x)
          {
              tot++;
              if(tot>k)break;//超过k就没有意义了 
              x^=(1<<i);
          }
        if((1<<(i-1))<=x)ans+=f[i-1][k-tot];
     }
    if(tot+x==k)ans++;//判断x本身 
    return ans;
}
int calc(int l,int r,int k)//统计0...x内二进制表示含k个1的数的个数
{
    int s,now=0;
    for(s=0;now<k;s++)now+=find(r,s)-find(l-1,s);
    s--;now=k-now+find(r,s)-find(l-1,s);
    int left=l;
    while(l<r)
     {
         int mid=(int)(((long long)l+(long long)r)>>1);//int+int会范围爆炸 
         if(find(mid,s)-find(left-1,s)>=now)r=mid;else l=mid+1;
     }
    return l;
}
int main()
{
    int TT,l,r,k;
    init();
    scanf("%d",&TT);
    while(TT--)
     {
         scanf("%d%d%d",&l,&r,&k);
         if(r<=0)
         {
             if(r==0)r--,k--;
             l^=(1<<31),r^=(1<<31);
             printf("%d
",(1<<31)|calc(l,r,k));
             continue;
         }
         if(l==0)l++,k--;
         printf("%d
",calc(l,r,k));
     }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/onioncyc/p/6704804.html