• bzoj4404: [Neerc2015]Binary vs Decimal


    WC结束了,来补一下这题的题解

    首先感谢SC神犇YYY(第一个AC此题的神犇)教我做法

    再感谢教YYY做法的Claris大爷

    首先,我们发现一个性质,一个合法的数的后缀必定是合法的,所以我们就可以bfs了,往合法的数的最高位加0或1

    只有最高位是1的数才有可能是答案

    YYY大爷告诉我们,并且不难证明任何时候队列中以0开头的数字数量小于等于以1开头的数字数量,并且每次进入合法节点最多只会生成一个不合法数字,因此整个搜索是O(n*处理每个节点的时间)的

    对于队列里的每个数,记录3个东西,十进制下的hash值,十进制长度len,二进制后len位

    同时维护当前10^len的二进制,由于是BFS,所以len只增不减

    最后有一个问题,队列里的元素不是有序的。这也很好办,对于相同长度的序列,只需要先全部加0,再全部加1

    具体细节可以看我的代码

    窝的代码是目前为止AC代码中最短的

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <cstdlib>
    #include <algorithm>
    #define ll long long
    #define N 23333
    #define L 170
    #define P 1000000009
    
    using namespace std;
    inline void multiply(int *a,int b){
    	int k=0;
    	for (int i=1;i<=a[0];++i){
    		a[i]=a[i]*b+k;
    		k=a[i]>>1;
    		a[i]=a[i]&1;
    	}
    	for (;a[0]<165&&k;k=k>>1) a[++a[0]]=k&1;
    }
    
    inline void add(int *a,const int *b){
    	a[0]=max(a[0],b[0]);
    	int k=0;
    	for (int i=1;i<=a[0];++i){
    		a[i]+=b[i]+k;
    		k=a[i]>>1;
    		a[i]=a[i]&1;
    	}
    	for (;a[0]<165&&k;k=k>>1) a[++a[0]]=k&1;
    }
    
    inline int gethash(int *a,int len){
    	int ret=0;
    	for (int i=1;i<=len;++i)
    		ret=((ll)ret*233%P+a[i])%P;
    	return ret;
    }
    
    void print(int *a,int len){
    	for (int i=len;i;--i) printf("%d",a[i]);
    	puts("");
    }
    
    struct node{
    	int hash,len;
    	int b[L];
    };
    node q[N];int qh,qt,lastqh,lastqt;
    int rank;
    int t[L];
    
    int main(){
    	scanf("%d",&rank);--rank;
    	if (!rank){puts("1");return 0;}
    	lastqh=qh=0;lastqt=qt=2;
    	q[1].len=1;q[1].hash=0;
    	q[1].b[0]=1;q[1].b[1]=0;
    	q[2].len=1;q[2].hash=1;
    	q[2].b[0]=1;q[2].b[1]=1;
    	t[0]=1;t[1]=1;
    	for (;;lastqh=qh,lastqt=qt){
    		multiply(t,10);
    		for (int k=0;k<2;++k){
    			qh=lastqh;
    			while (qh<lastqt){
    				q[++qt]=q[++qh];
    				++q[qt].len;
    				q[qt].hash=((ll)q[qt].hash*233%P+k)%P;
    				if (k) add(q[qt].b,t);
    				if (q[qt].hash!=gethash(q[qt].b,q[qt].len)) --qt;
    				else if (k) --rank;
    				if (!rank){
    					print(q[qt].b,q[qt].len);
    					return 0;
    				}
    			}
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    APUE学习笔记:第四章 文件和目录
    APUE学习笔记:第三章 文件I/O
    APUE学习笔记:第二章 UNIX标准化及实现
    APUE学习笔记:第一章 UNUX基础知识
    《数据库系统概念》学习笔记2
    go语言下载地址
    Centos7 编译 android4.4
    剑侠情缘新进展
    ubuntu server 14.04手动安装svn
    ubuntu server 14.04 lts显示乱码的问题
  • 原文地址:https://www.cnblogs.com/wangyurzee7/p/5177227.html
Copyright © 2020-2023  润新知