• bzoj 4725 [POI2017]Reprezentacje ró?nicowe


    如果只要求做出来这个题的话还是非常简单的。

    直接用题目中所给的性质暴力logw级别的数列然后二分就行了,非常傻逼。

    证明:不存在$f[b]-f[a]==f[r]-f[l] (b>a,r>l)$

    首先不妨设$b>r,a>l$

    1>当b为奇数时

    $f[b]-f[a]>=f[b-1],f[r]-f[l]<f[b-1]$故不成立。

    2>当b为偶数时

    (1)$a==b-1$ 

    根据定义$f[b]f-[a]$是之前未出现过的。

    (2)$a<b-1$

    显然若$r<b-1$则一定不成立(差一定小于f[b-2])。

    当$r==b-1$时

    $f[b]-f[a]==f[b-1]-f[l]$ --> $f[b-1]==f[a]-f[l]$但显然$f[b-1]>f[a]-f[l]$

    所以每个数都由唯一一对$(r,l)$来表示。

    显然当$f[x]>1e9$时乘2的操作就没有影响了,所以之可能是偶数项和前一项的差,直接二分算出第几个即可。

    #include <bits/stdc++.h>
    #define min(a,b) ((a)<(b)?(a):(b))
    #define max(a,b) ((a)>(b)?(a):(b))
    #define for1(a,b,i) for(int i=a;i<=b;++i)
    #define FOR2(a,b,i) for(int i=a;i>=b;--i)
    using namespace std;
    typedef long long ll;
    inline int read() {
        int f=1,sum=0;
        char x=getchar();
        for(;(x<'0'||x>'9');x=getchar()) if(x=='-') f=-1;
        for(;x>='0'&&x<='9';x=getchar()) sum=sum*10+x-'0';
        return f*sum;
    }
    
    #define N 58
    #define M 105
    ll f[M];
    bool vis[M*M];
    int dui[M*M];
    map <ll,pair<int,int> > st;
    
    int main () {
        //freopen("a.in","r",stdin);
        f[1]=1,f[2]=2,f[3]=4,f[4]=8;
        for1(5,N,i) {
            if(i&1) f[i]=f[i-1]*2;
            else {
                int head=1;
                for1(1,i-1,j) for1(1,j-1,k) {
                    if(f[j]-f[k]<=i*i) vis[f[j]-f[k]]=1;
                    while (vis[head]) ++head;
                }
                f[i]=f[i-1]+head;
                for1(1,i-1,j) for1(1,j-1,k) 
                    if(f[j]-f[k]<=i*i) vis[f[j]-f[k]]=0;
            }
        }
        for1(1,N,i) for1(1,i-1,j) {
            st[f[i]-f[j]]=make_pair(i,j);
            if(f[i]-f[j]<=1e9) dui[++dui[0]]=f[i]-f[j];
        }
        sort(dui+1,dui+dui[0]+1);
        int n=read();
        while (n--) {
            int x=read();
            if(st.count(x)) {
                pair<int,int> t=st[x];
                printf("%d %d
    ",t.first,t.second);
            }
            else {
                int l=1,r=dui[0],mid,ans=0;
                while (l<=r) {
                    mid=l+r>>1;
                    if(dui[mid]<x) l=mid+1,ans=mid;
                    else r=mid-1;
                }
                //cout<<ans<<endl;
                printf("%d %d
    ",N+2*(x-ans),N+2*(x-ans)-1);
            }
        }
    }
  • 相关阅读:
    用移动硬盘代替DVD安装单系统Vista方法
    背完这444句,你的口语绝对不成问题了
    DataGridView 只能输入整数解决方案
    转载:Firefox的失败在中国几乎就是命中注定
    ZBlog 添加运行天数
    并行和串行通信
    ZBlog 添加收藏本站
    ITPUB调查高达42%的DBA由开发人员转变而成
    DataGridView 只能输入整数解决方案
    用移动硬盘代替DVD安装单系统Vista方法
  • 原文地址:https://www.cnblogs.com/asd123www/p/9628867.html
Copyright © 2020-2023  润新知