zoukankan      html  css  js  c++  java
  • BZOJ 4725: [POI2017]Reprezentacje ró?nicowe

    Description

    一个数列.

    (a_1=1,a_2=2)

    当 (n>2) 时

    [a_n = {  egin {matrix} 2a_{n-1}, ext{n is an odd number} \ a_{n-1}+r_{n-1}, ext{ n is an even number } end{matrix} ]

    (S_n={a_i-a_j,1 leqslant j<ileqslant n})

    (r_n) 为最小不在 (S_n) 中的非负整数.

    给出 (x),求一对 ((p,q)) 使得 (a_p-a_q=x)

    Sol

    打表+二分.

    可以发现 ({a_n}) 是一个单调递增的数列,而且有 (*2) 的递推式存在,所以当 (n>2log_2 10^9) 的时候小于 (10^9) 的差只可能是相邻的两个数字.

    对于前面几行的元素直接打表存起来,后面的就二分一下在表内的元素算一下就可以了.

    Code

    /**************************************************************
        Problem: 4725
        User: BeiYu
        Language: C++
        Result: Accepted
        Time:568 ms
        Memory:5280 kb
    ****************************************************************/
     
    #include <cstdio>
    #include <utility>
    #include <map>
    #include <iostream>
    using namespace std;
     
    #define mpr make_pair
    typedef long long LL;
    typedef pair< LL,LL > pr;
    const int N = 505;
     
    LL p=1,n=65,m,T;
    map< LL,pr > mp;
    LL a[N][N];
    LL b[N*N];
     
    inline LL in(LL x=0,char ch=getchar()){ while(ch>'9' || ch<'0') ch=getchar();
        while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();return x; }
     
    void _add(LL x,pr y){ mp[x]=y; }
    LL _get(){ while(mp.count(p)) p++;return p; }
     
    int main(){
        a[2][1]=1,mp[1]=mpr(2,1);
        for(int i=3;i<=n;i++){
            if(i&1){
                for(int j=1;j<i;j++) a[i][i-1]+=a[j][j-1];
                a[i][i-1]+=1;
            }else{
                a[i][i-1]=_get();
            }
            _add(a[i][i-1],pr(i,i-1));
            for(int j=1;j<i-1;j++){
                a[i][j]=a[i-1][j]+a[i][i-1];
                _add(a[i][j],pr(i,j));
            }
        }
         
        for(map< LL,pr >::iterator it=mp.begin();it!=mp.end();it++) b[++m]=(*it).first;
         
        for(T=in();T--;){
            LL l=1,r=m,mid,x;
            x=in();
            if(mp.count(x)){ printf("%lld %lld
    ",mp[x].first,mp[x].second);continue; } 
            while(l<=r){
                mid=(l+r)>>1;
                if(b[mid]<x) l=mid+1;
                else r=mid-1;
            }
            printf("%lld %lld
    ",n+(x-r)*2-1,n+(x-r)*2-2);
        }return 0;
    }
    

      

  • 相关阅读:
    python学习Day21--内置函数、反射
    python学习Day20--属性、类方法和静态方法+类多继承算法补充
    python学习Day19--面向对象的三大特性
    python学习Day18--继承
    python学习Day17--名称空间
    python学习Day16--面向对象
    python学习Day15--递归与二分查找
    python学习Day14--内置函数
    c# 深克隆与浅克隆
    css test-align 和 margin 居中什么区别
  • 原文地址:https://www.cnblogs.com/beiyuoi/p/6142935.html
Copyright © 2011-2022 走看看