hdu5898 数位dp+预处理 odd-even number
来源:互联网 发布:mac下载器 编辑:程序博客网 时间:2024/05/17 03:21
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<time.h>using namespace std;#define ll long longint a[25];ll dp[25][2],tp[25][25],dpp[25][2],tpp[25];ll pow(int k){ll num=1;for(int i=0;i<k;i++)num*=5;return num;}void init(){dp[0][0]=0,dp[0][1]=dpp[0][1]=1;dp[1][1]=dp[2][0]=0;dpp[1][1]=dpp[2][0]=0;dpp[2][1]=25,dpp[1][0]=5;dp[2][1]=25,dp[1][0]=5;dp[3][1]=100,dp[3][0]=225;dpp[3][1]=125,dpp[3][0]=250;for(int i=4;i<20;i++){dp[i][1]=(dp[i-2][0]+dp[i-2][1])*25;dp[i][0]=dp[i-1][1]*5+dp[i-2][0]*25;dpp[i][1]=(dpp[i-2][1]+dpp[i-2][0])*25;dpp[i][0]=dpp[i-1][1]*5+dpp[i-2][0]*25;}tpp[0]=1;for(int i=1;i<20;i++){tp[0][i]=dpp[i][1];tpp[i]=tp[0][i];for(int j=2;j<=i;j+=2){tp[j][i]=pow(j)*(dpp[i-j][1]);tpp[i]+=tp[j][i];}}}int f(int l,int r){int i,cnt1=0,cnt2=0,flag=a[l]&1;for(i=l;i<r;i++){if((a[i]&1)!=flag) {if((cnt1&1)||((!(cnt2&1))&&cnt2))return 0;else { flag=a[i]&1; cnt1=cnt2=0; i--; }}else{ if(a[i]&1) cnt1++; else cnt2++;}}if((cnt1&1)||((!(cnt2&1))&&cnt2))return 0;return 1;}ll solve(ll x){int cnt=0,i,j;ll sum=0;memset(a,0,sizeof(a));while(x){a[cnt++]=x%10;x/=10;}if(cnt<=1) return a[0]/2+1;for(i=1;i<cnt;i++) sum+=dp[i][0]+dp[i][1];for(i=0;i<cnt;i++){ //cout<<sum<<endl;if(i+1==cnt){sum+=a[i]/2*5*(dpp[i-1][0]+dpp[i-1][1]);sum+=(a[i]-1)/2*tpp[i];return sum;}int cntt=0;for(j=i+1;j<cnt&&((a[i+1]&1)==(a[j]&1));j++,cntt++);if(j>=cnt||f(j,cnt)){if(cntt&1){if(a[i+1]&1){if(i)sum+=a[i]/2*(dpp[i][0]+dpp[i][1]);elsesum+=(a[i]+1)/2*(dpp[i][0]+dpp[i][1]);}else{if(i){sum+=a[i]/2*5*(dpp[i-1][0]+dpp[i-1][1]);sum+=((a[i]+1)/2)*5*tpp[i-1];}}}else{if(a[i+1]&1){if(i==0)sum+=a[i]/2+1;else{sum+=a[i]/2*5*(dpp[i-1][1]+dpp[i-1][0]);sum+=((a[i]+1)/2)*tpp[i];}}else{if(!i)sum+=a[i]/2+1;elsesum+=((a[i]+1)/2)*tpp[i];}}}}return sum;}typedef long long llong;const int MAX_DIGIT = 30;int digit[MAX_DIGIT];llong dppp[MAX_DIGIT][10][2][2];//当前是第i位,前一位是pre,是否存在前导零,当前是否已经满足要求,是否需要限制llong dfs(int i, int pre, bool zero, bool yes, bool limit){ //此时如果满足条件则返回1个 if (i == -1) { return yes; } //枚举到的最大数,不需要限制时为9 int max_digit = limit ? digit[i] : 9; llong& dpnow = dppp[i][pre][zero][yes]; //如果不需要限制且dp值不为-1,直接返回dp值,即记忆化 if (!limit && dpnow != -1) { return dpnow; } llong ans = 0; //now==0时zero为true,now为偶数时yes为true,当前有限制且now为最大数则仍然需要限制 if (zero) { for (int now = 0; now <= max_digit; ++now) { ans += dfs(i - 1, now, now == 0, !(now & 1), limit && now == max_digit); } } //此时zero一定为false,只有前一位是奇数now是偶数时yes为true,是否需要限制同上 else if (yes) { for (int now = 0; now <= max_digit; ++now) { ans += dfs(i - 1, now, false, (pre & 1) && !(now & 1), limit && now == max_digit); } } //当前是不满足条件的,为了满足条件,now必须跟pre奇偶性相同,此时yes一定为true else { for (int now = (pre & 1); now <= max_digit; now += 2) { ans += dfs(i - 1, now, false, true, limit && now == max_digit); } } //更新dp值,记忆化 if (!limit) { dpnow = ans; } return ans;}llong count_odd_even(llong n) //数0-n范围内有多少满足条件的数{ if (n == 0) { return 1; } int length = 0; //将n数位分离并存入digit数组 for (; n; n /= 10) { digit[length] = n % 10; length += 1; } return dfs(length - 1, 0, true, true, true);}int main(){ //freopen("mydata.txt", "w", stdout);ll t,l,r,temp;srand(time(NULL));int cas=0;init();scanf("%I64d",&t);while(t--&&scanf("%I64d%I64d",&l,&r)!=EOF) { /*l=r=0; while(l>=r) {l=rand(); r=rand();} if(solve(r)-solve(l-1)!=count_odd_even(r)-count_odd_even(l-1)) cout<<l<<' '<<r<<endl;*/ printf("Case #%d: %I64d\n",++cas,solve(r)-solve(l-1)); //cout<<solve(r)<<endl; /*for(r=10000;r<1e12;r+=10000) { temp=solve(r)-solve(0); printf("%I64d\n",temp); }*/ }return 0;}/*20434 212162725 2399619777 23563630 3154410223 199805785 123873446 288232108 118043300 140794280 13758*/
0 0
- hdu5898 数位dp+预处理 odd-even number
- hdu5898 odd-even number 【数位DP】
- hdu5898 odd-even number(数位dp)
- hdu5898 odd-even number(数位dp)
- hdu5898 odd-even number(数位DP)
- HDU5898 odd-even number(数位dp)
- hdu5898 odd-even number (数位DP)
- HDU5898 odd-even number (数位DP)shenyang网赛
- hdu5898 odd-even number
- hdu5898 odd-even number
- 【hdu5898】【数位DP】odd-even number 【连续奇数长度为偶数,连续的偶数的长度是奇数】
- [hdu 5898 odd-even number] 数位DP
- Hdu-5898 odd-even number(数位DP)
- HDU 5898 odd-even number(数位dp)
- hdu 5898 odd-even number (数位dp)
- HDU odd-even number 数位dp
- odd-even number (数位dp)
- 【HDU5898 2016 ACM ICPC Asia Regional Shenyang Online G】【数位DP】odd-even number 范围内有多少数字满足奇串长为偶数偶串长为奇数.
- ViewPager的小红点跟随效果
- SpringMVC-轻量级Web框架
- JAVA-Properties
- ionic之android真机CSS样式失效 $ionicActionSheet
- Exceptional C++学习笔记(2) 多态
- hdu5898 数位dp+预处理 odd-even number
- ROS下使用科大讯飞SDK进行在线语音识别 (导入第三方库文件)
- LeetCode | 5)Longest Palindromic Substring
- EasyUI——datagrid 的onLoadSuccess事件无数据时提示“没有相关记录”——给用户更好的视觉效果
- 自定义天气显示温度变化的LinearChart控件
- Andriod自定义组件
- HDU5127 Dogs' Candies 暴力+list
- Latex 表格图片公式跨双栏显示并使标题居中以及表格图片注释技巧
- c++第二周初学