bzoj 1223: [HNOI2002]Kathy函数 数位DP 高精度
1223: [HNOI2002]Kathy函数
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 207 Solved: 90
[Submit][Status]
Description
Input
仅有一行,为正整数m
Output
输出仅有一个正整数,表示所有的满足f(n)=n,(n<=m) 的自然数的个数。
Sample Input
Sample Output
这道题的高精度模板相对又有完善,但还存在bugs,使用时尽量讲位数多开几倍。
这道题由于递归方程转移有2、4,所以应该往二进制那边去想,可以通过归纳法证明f(n)=n当且仅当n二进制为回文串(相当神奇),然后就是数位DP,最开始我将数据范围想成了m<=2^100,还说刚好long long可以存,但是10^100就必须写高精了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<unistd.h>
using namespace std;
typedef long long qword;
#define MAXN 20100
class number//四位
{
public:
const static int max_val=;
const static int max_len=;
number()
{
clear();
}
number(int x)
{
*this=x;
}
bool is_odd()const
{
return numb[]%==;
}
bool is_even()const
{
return numb[]%==;
}
int size()const
{
return topn;
}
int length()const
{
int x=numb[topn];
int ret=;
while (x)
{
ret++;
x/=;
}
int y=;
x=number::max_val;
while (x)
{
y++;
x/=;
}
y--;
ret+=topn*y;
return ret;
}
number pow(int x)const
{
number ret,a;
a=*this;
ret=;
while (x)
{
if (x&)ret=ret*a;
a=a*a;
x>>=;
}
return ret;
}
void operator =(int x)//{{{
{
int now=;
clear();
numb[now]=x;
while (numb[now]>=number::max_val)
{
numb[now+]+=numb[now]/number::max_val;
numb[now]%=number::max_val;
now++;
if (now>topn)topn=now;
}
}//}}}
void operator =(number num)
{
topn=num.topn;
memcpy((this->numb),num.numb,sizeof(num.numb[])*(topn+));
}
void operator +=(number num)//{{{
{
int i;
topn=max(topn,num.topn);
for (i=;i<=topn;i++)
{
numb[i]+=num.numb[i];;
if (numb[i]>=number::max_val)
{
numb[i+]+=numb[i]/number::max_val;
numb[i]%=number::max_val;
}
}
while (numb[topn+])
{
topn++;
numb[topn+]+=numb[topn]/number::max_val;
numb[topn]%=number::max_val;
}
}//}}}
void operator +=(int x)//{{{
{
int now=;
if (topn==-)topn=;
numb[now]+=x;
while (numb[now]>=number::max_val)
{
numb[now+]+=numb[now]/number::max_val;
numb[now]%=number::max_val;
now++;
if (now>topn)topn=now;
}
}//}}}
void operator *=(int x)//{{{
{
int i;
for (i=;i<=topn;i++)
{
numb[i]*=x;
}
for (i=;i<=topn;i++)
{
if (numb[i]>=number::max_val)
{
numb[i+]+=numb[i]/number::max_val;
numb[i]%=number::max_val;
}
}
while (numb[topn+])
{
topn++;
numb[topn+]+=numb[topn]/number::max_val;
numb[topn]%=number::max_val;
}
}//}}}
void operator -=(number &num)//{{{
{
if (*this<num)throw "Error!\n->void operator -=(number &num)\n";
int i;
for (i=;i<=topn;i++)
{
numb[i]-=num.numb[i];
}
for (i=;i<=topn;i++)
{
while (numb[i]<)
{
numb[i]+=number::max_val;
numb[i+]--;
}
}
while (topn&&!numb[topn])topn--;
}//}}}
void operator --(int)//{{{
{
if (topn==&&numb[]==)throw "Error!\n->void operator --(int)\n";
int now=;
numb[now]--;
while (numb[now]<)
{
numb[now+]--;
numb[now]+=number::max_val;
}
while (topn&&!numb[topn])topn--;
}//}}}
private:
int numb[max_len];
int topn;
void clear()
{
topn=;
memset(numb,,sizeof(numb)); }
friend bool operator <(number num1,number num2);
friend bool operator <=(number num1,number num2);
friend bool operator ==(number num1,number num2);
friend ostream& operator <<(ostream &out,number num);
friend istream& operator >>(istream &in,number &num);
friend number operator *(number num1,number num2);
friend number operator *(number num,int x);
friend number operator +(number num1,number num2);
//a=a+b远没有a+=b快
};
bool operator <(number num1,number num2)//{{{
{
if (num1.topn!=num2.topn)
{
return num1.topn<num2.topn;
}
int i;
for (i=num1.topn;i>=;i--)
{
if (num1.numb[i]!=num2.numb[i])
{
return num1.numb[i]<num2.numb[i];
}
}
return false;
}//}}}
bool operator <=(number num1,number num2)//{{{
{
if (num1.topn!=num2.topn)
{
return num1.topn<num2.topn;
}
int i;
for (i=num1.topn;i>=;i--)
{
if (num1.numb[i]!=num2.numb[i])
{
return num1.numb[i]<num2.numb[i];
}
}
return true;
}//}}}
bool operator ==(number num1,number num2)//{{{
{
if (num1.topn!=num2.topn)return false;
for (int i=;i<=num1.topn;i++)
{
if (num1.numb[i]!=num2.numb[i])return false;
}
return true;
}//}}}
ostream& operator <<(ostream &out,number num)//{{{
{
int i;
out<<num.numb[num.topn];
for (i=num.topn-;i>=;i--)
{
//压六位时
//if (num.numb[i]<100000)out<<"0";
//if (num.numb[i]<10000)out<<"0";
if (num.numb[i]<)out<<"";
if (num.numb[i]<)out<<"";
if (num.numb[i]<)out<<"";
out<<num.numb[i];
}
return out;
}//}}}
istream& operator >>(istream &in,number &num)//{{{
{
string str;
in>>str;
int i;
num.clear();
for (i=(int)str.length()-,num.topn=;i>=;i-=,num.topn++)
{
if (i-<(int)str.length())
{
num.numb[num.topn]=(str[i]-'')+*(str[i-]-'')+*(str[i-]-'')+*(str[i-]-'');
}else
{
if (i-<(int)str.length())num.numb[num.topn]+=*(str[i-]-'');
if (i-<(int)str.length())num.numb[num.topn]+=*(str[i-]-'');
if (i<(int)str.length())num.numb[num.topn]+=(str[i]-'');
}
}
num.topn--;
return in;
}//}}}
number operator *(number num,int x)//{{{
{
number ret;
ret=num;
ret*=x;
return ret;
}//}}}
number operator *(number num1,number num2)
{
number ret;
ret.topn=num1.topn+num2.topn;
for (int i=;i<=num1.topn;i++)
for (int j=;j<=num2.topn;j++)
{
ret.numb[i+j]+=num1.numb[i]*num2.numb[j];
ret.numb[i+j+]+=ret.numb[i+j]/number::max_val;
ret.numb[i+j]%=number::max_val;
}
for (int i=;i<=ret.topn;i++)
{
ret.numb[i+]+=ret.numb[i]/number::max_val;
ret.numb[i]%=number::max_val;
}
while (ret.numb[ret.topn+])
{
ret.topn++;
ret.numb[ret.topn+]+=ret.numb[ret.topn]/number::max_val;
ret.numb[ret.topn]%=number::max_val;
}
while (ret.topn && !ret.numb[ret.topn])
{
ret.topn--;
}
return ret;
}
number operator +(number num1,number num2)//{{{
{
number ret;
ret=num1;
ret+=num2;
return ret;
}//}}} char str[MAXN];
int num0[MAXN];
bool num[MAXN];
number rec[MAXN][][];
int n,m;
number search_m(int now,int fl,int bo)
{
int x,y;
x=now-;y=n-now;
if (x>y)
{
number ret;
ret=(int)(fl || (!fl && !bo));
return ret;
}
number &res=rec[now][fl][bo];
number aa;
if (aa<rec[now][fl][bo])return res;
res=;
if (!fl)
{
if (num[y])
{
//
if (num[x]==)
res+=search_m(now+,false,bo);//
else
res+=search_m(now+,false,true);// if (now>)//首位非0
{
if (num[x]==)
res+=search_m(now+,true,false);//
else
res+=search_m(now+,true,bo);//
}
}else if (!num[y])
{
if (now>)//特殊处理m==0情况
{
if (num[x]==)
res+=search_m(now+,false,false);//
else
res+=search_m(now+,false,bo);//
}
}
}else
{
res+=search_m(now+,true,true);//
res+=search_m(now+,true,true);//
}
return res;
}
int main()
{
//freopen("input.txt","r",stdin);
scanf("%s\n",str);
int i,j,x,y;
n=strlen(str);
x=y=-;
for (i=n-;i>=;i-=)
{
x++;
for (j=max(,i-);j<=i;j++)
num0[x]=num0[x]*+str[j]-'';
}
n=x+;
x=;
while (~n)
{
num[x++]=num0[]%;
for (i=n-;i>=;i--)
{
if (i)num0[i-]+=(num0[i]&)*;
num0[i]/=;
}
while (n>= && !num0[n-])n--;
}
n=x;
/*for (i=n-1;i>=0;i--)
{
printf("%d",num[i]);
}
printf("\n");*/
/*for (i=0;i<=n;i++)
for (j=0;j<2;j++)
for (k=0;k<2;k++)
rec[i][j][k]=-1;*/
number ans;
ans=search_m(,false,false);
number xx;
for (i=;i<n;i++)
{
xx=;
xx=xx.pow((i-)/);
ans+=xx;
}
cout<<ans<<endl;
return ;
}
bzoj 1223: [HNOI2002]Kathy函数 数位DP 高精度的更多相关文章
- 【SPOJ 2319】 BIGSEQ - Sequence (数位DP+高精度)
BIGSEQ - Sequence You are given the sequence of all K-digit binary numbers: 0, 1,..., 2K-1. You need ...
- BZOJ.4513.[SDOI2016]储能表(数位DP)
BZOJ 洛谷 切了一道简单的数位DP,终于有些没白做题的感觉了...(然而mjt更强没做过这类的题也切了orz) 看部分分,如果\(k=0\),就是求\(\sum_{i=0}^n\sum_{j=0} ...
- [bzoj 1026]windy数(数位DP)
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1026 分析: 简单的数位DP啦 f[i][j]表示数字有i位,最高位的数值为j的windy数总 ...
- bzoj 1026 [SCOI2009]windy数 数位dp
1026: [SCOI2009]windy数 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline ...
- bzoj 3131 [Sdoi2013]淘金(数位DP+优先队列)
Description 小Z在玩一个叫做<淘金者>的游戏.游戏的世界是一个二维坐标.X轴.Y轴坐标范围均为1..N.初始的时候,所有的整数坐标点上均有一块金子,共N*N块. 一阵风吹 ...
- BZOJ 4513: [Sdoi2016]储能表 [数位DP !]
4513: [Sdoi2016]储能表 题意:求\[ \sum_{i=0}^{n-1}\sum_{j=0}^{m-1} max((i\oplus j)-k,0) \] 写出来好开心啊...虽然思路不完 ...
- BZOJ 4521 CQOI 2016 手机号码 数位DP
4521: [Cqoi2016]手机号码 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 539 Solved: 325[Submit][Status ...
- BZOJ 2425 [HAOI2010]计数:数位dp + 组合数
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2425 题意: 给你一个数字n,长度不超过50. 你可以将这个数字: (1)去掉若干个0 ( ...
- bzoj 3131 [Sdoi2013]淘金(数位dp)
题目描述 小Z在玩一个叫做<淘金者>的游戏.游戏的世界是一个二维坐标.X轴.Y轴坐标范围均为1..N.初始的时候,所有的整数坐标点上均有一块金子,共N*N块. 一阵风吹过,金子的位置发生了 ...
随机推荐
- Linux发送监控指标到内部邮箱
数据库的健康监控是个很重要的工作.重要的指标\KPI监控结果会有专门的採集.监控.告警系统来做相关事情. 而一些不是很重要的或者还在设计和调试阶段的相关指标,我仅仅是想发送到我自己邮箱,本文就针对在s ...
- 实现FTP断点续传
应用需求: 网盘开发工作逐步进入各部分的整合阶段,当用户在客户端修改或新增加一个文件时,该文件要同步上传到服务器端对应的用户目录下,因此针对数据传输(即:上传.下载)这一块现在既定了三种传输方式,即: ...
- 总结如何实现Android浮动层,主要是dialog的使用
自定义一个类继承自Dialog类,然后在构造方法中,定义这个dialog的布局和一些初始化信息. 查看源码打印? 01 public class MenuDialog extends Dialog { ...
- php并发处理
最近某个项目用php生成文件,但是由于文件量太大,单个进程生成需要很长的时间,所以想并发进行处理. 网上查找了下相关的资料,php本身是没有多线程的概念的,那就只能用多进程了,再找资料却是 ...
- Bootstarp--全局CSS样式之表格
表格在实际开发中可以说是非常常见的,但是有很多人不喜欢使用表格,但个人觉得在简单的界面布局中使用表格还是很简单的.毕竟人家给了表格这元素,而你却不去使用,貌似有点不解风情. 下面简单介绍Bootstr ...
- s标签可以if elseif else
首先引用s标签: <%@ taglib prefix="s" uri="/struts-tags" %> 使用s标签进行if elseif else ...
- Java-hibernate的Hello World
hibernate 是对jdbc进行轻量级封装的 orm 框架,充当项目的持久层. 要使用 hibernate首先就需要继续配置, 引包:下载hibernate然后加入jar包 同时引入mysql ...
- 关于 ORA - 01861 文字与格式字符串不匹配问题(oracle存储过程)
一般问题(TO_DATE 和 TO_CHAR 两种格式互换)比如: 只要转化下格式就OK ,这里就不详细解释这两种格式的用法了! 今天把之前做好的模块拿到当地实习,不管怎么测 ,连续测试了好几个存储过 ...
- vs2015中ctrl+shift+F进行“在文件中查找”,有时候无效?
搜狗拼音的默认简繁切换快捷键是ctrl+shift+F,改掉以后vs就可以收到这个按键消息了
- 关于AfterLogic WebMail 的.net版无法上传控件的解决办法
在使用AfterLogic WebMail做客户端的时候发现无论是在FF下还是在IE下发送邮件时附件怎么也无法上传,后来查看代码发现它使用的FLASH上传调用的上传代码是upload.php,问题就出 ...