sgu255:Winsock 3 Beta(二进制分析)

题目大意:
       定义 A(p)={x|xp,x31},f(x)=|A(2x)A(x)|
       n(n100) 组数据,每组数据给出 m(m2311) ,询问 f(x)=m 是否有唯一解。

分析:
       我们考虑 f(x)f(x+1) 的变化。
       如果 x+1 满足条件,那么 2(x+1) 必定也满足条件,去掉 x+1 新添一个 2(x+1) f(x)f(x+1) 便只受 2x+1 的影响。
       如果 x+1 不满足条件,那么 2(x+1) 必定也不满足条件, f(x)f(x+1) 仍只受 2x+1 的影响。
       综上, f(x)f(x+1) 只受 2x+1 的影响, 2x+1 为奇数。
       如果 2x+1 满足条件,那么 f(x+1)=f(x)+1 ,否则 f(x+1)=f(x)
       f(x)=m 有唯一解,那么第 m 个满足条件的奇数+2= m+1 个满足条件的奇数。也就是说第 m 个满足条件的奇数形如100..011,既满足末两位为 1 ,另一个1与末两位之间至少有一个 0
      至于怎么求第 m 个满足条件的奇数,数学方法or数位 dp 均可。

AC code:

#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <string>
#include <sstream>
#include <iostream>
#include <map>
#include <set>
#include <list>
#include <stack>
#include <queue>
#include <vector>
#define pb push_back
#define mp make_pair
typedef long long LL;
typedef double DB;
typedef long double LD;
using namespace std;

int a[4];
int num[100000][4];

void pre()
{
    for(int i = 0; i <= 100000; ++i)
    {
        if(!i) num[i][1] = 1;
        if(i) num[i][2] = 1;
        if(i > 1) num[i][3] = i-1;
    }
}

int main()
{
    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #endif

    pre();
    int Test, n;
    scanf("%d", &Test);
    while(Test--)
    {
        scanf("%d", &n);
        for(int i = 2; i <= 100000; ++i)
            if(num[i][3] < n) n -= num[i][3];
            else {a[3] = i;break;}
        for(int i = 1; i <= 100000; ++i)
            if(num[i][2] < n) n -= num[i][2];
            else {a[2] = i;break;}
        for(int i = 0; i <= 100000; ++i)
            if(num[i][1] < n) n -= num[i][1];
            else {a[1] = i;break;}
        if(a[1] == 0 && a[2] == 1 && a[3] > 2) puts("YES");
        else puts("NO");
    }
    #ifndef ONLINE_JUDGE
    fclose(stdin);
    fclose(stdout);
    #endif
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值