题目链接

坑:

1.ll x,y;

z=x*y;可能会溢出,于是我写成x%mod*y%mod

仍旧错误,要写成x%mod*(y%mod).

2.f(9019)=1.

要注意如果为0,下一位的符号根据0的个数而变化

 #include<iostream>
 #include<stdio.h>
 #include<algorithm>
 #include<queue>
 #include<math.h>
 #include<string.h>
 #include<string>
 #include<stdlib.h>
 using namespace std;
 typedef long long ll;
 typedef unsigned long long ull;
 #define re(i,n) for(int i=0;i<n;i++)
 ;
 /*
 Node cnt表示个数,sum表示和
 */
 struct Node{
     ll cnt, sum;
     Node() :cnt(), sum(){}
     Node(ll c, ll s) :cnt(c), sum(s){}
 }dp[][][][];//(bits,+-,+-can change,sum)
 /*
 19 最多19位
 2  +还是-
 2  是否是第一个数字
 600 f(n)的结果,因为19位*9=171,输入的k是-100到100,所以范围大概是-300到+300,所以用600
 */
 ll ten[];
 //ten[i]表示10^i
 void init(){
     ten[] = ;
     ; i < ; i++){
         ten[i] =  * ten[i - ];
     }
 }
 /*d是一个大管家,管理者dp这个数组,如果计算过,那就不再计算了
 对参数做一些处理,像适配器一样
 n表示[0,10^n-1]范围内,第一个符号为flag,符号是否会改变change,f(n)=k
 */
 Node d(int n, int flag, int change, int k){
      ?  : );
     ;
     Node f(ll,int, int, int);
     ){
         dp[n][ff][change][kk] = f(ten[n] - , flag, change, k);
     }
     return dp[n][ff][change][kk];
 }
 /*
 主要逻辑都在这个函数里面,n表示[0,n]范围内的值
 */
 Node f(ll n, int flag, int change, int k){
     ), );
     ){
          && flag*k <= n), flag*k);
         , );
     }
     ll mi = , h = ;
     )h = tmp % , mi++;
     mi--;
     ll va = h*ten[mi];//处理清楚最高位
     Node t = d(mi, change ?  : -flag, change, k); //第一位为0时,有多少种情况
     Node ans = t;
     ; i < h; i++){
         t = d(mi, -flag, , k - flag*i);
         ans.cnt += t.cnt;
         ans.sum = (ans.sum + ten[mi]%mod*i*( t.cnt%mod) + t.sum) % mod;
     }
     //第一位为h时的情况
     )?flag:-flag);
     ){
         ff *= -;
     }
     t = f(n - va, ff, , k - flag*h);
     ans.cnt += t.cnt;
     ans.sum = (ans.sum + va%mod*(t.cnt%mod) + t.sum) % mod;
     return ans;
 }
 int main(){
     //freopen("in.txt", "r", stdin);
     init();
     memset(dp, -, sizeof(dp));
     ll l, r, k;
     cin >> l >> r >> k;
     Node m = f(l - , ,, k), n = f( r, ,, k);
     ll ans = (n.sum - m.sum) % mod;
     )ans += mod;
     cout << ans << endl;
     ;
 }

别人的代码还精简,算法更好.

 struct node
 {
     ll cnt,sum; //分别表示该状态的出现的次数,以及数字和
     node(ll _cnt,ll _sum):cnt(_cnt),sum(_sum){}
     node(){}
 }dp[][][]; //dp[i][j][k],表示当前在的i位,第一位有效位为j,交错和为k-100的状态
 ll num[];
 ll ten[];
 ll l,r;
 int k;
 node dfs(int cur,int first,int sum,bool limit)
 {
     )
         );
     ].cnt != -) ];
     ;
     node ret(,),tv;
     rep(i,up+)
     {
         int g;
          ?  : cur); }
         else g = first;
         if(g)
             tv = dfs(cur-,g,sum+((g-cur)%==?:-)*i,limit && i == up);
         else
             tv = dfs(cur-,,,limit && i==up);
         ll t = i*ten[cur-]%mod;
         ret.cnt = (ret.cnt + tv.cnt) % mod; //次数相加
         ret.sum = (ret.sum + tv.sum + t*tv.cnt)%mod; //和相加
     }
     ] = ret;
     return ret;
 }
 ll solve(ll n)
 {
     ) ;
     ;
     while(n){
         num[++len] = n % ;
         n /= ;
     }
     ,,).sum;
 }
 void init()
 {
     memset(dp,-,sizeof(dp));
     ten[] = ;
     ;i<;i++) ten[i] = (ten[i-] * ) % mod;
 }
 int main()
 {
 #ifndef ONLINE_JUDGE
     freopen("in.txt","r",stdin);
     // freopen("out.txt","w",stdout);
 #endif
     init();
     while(~scanf("%lld%lld%d",&l,&r,&k))
     {
         cout<<(solve(r)-solve(l-)+mod)%mod<<'\n';
     }
     ;
 }  

hihocoder1033交错和的更多相关文章

  1. hihoCoder1033 交错和 数位DP

    题目:交错和 链接:http://hihocoder.com/problemset/problem/1033# 题意:对于一个十进制整数x,令a0.a1.a2.....an是x从高位到低位的数位,定义 ...

  2. 【hihoCoder】1033: 交错和

    初探数位dp 介绍了数位类统计的基础知识.以下列出其中的基础点: 基本问题 统计在区间[l, r]中满足条件的数的个数 思路 1. [l, r] 将问题转换为 在[0, r]中满足条件的个数 - 在[ ...

  3. hiho#1033 : 交错和

    描述 给定一个数 x,设它十进制展从高位到低位上的数位依次是 a0, a1, ..., an - 1,定义交错和函数: f(x) = a0 - a1 + a2 - ... + ( - 1)n - 1a ...

  4. hihoCoder #1033 : 交错和 (数位Dp)

    题目大意: 给定一个数 x,设它十进制展从高位到低位上的数位依次是 a0, a1, ..., an - 1,定义交错和函数: f(x) = a0 - a1 + a2 - ... + ( - 1)n - ...

  5. [hihocoder 1033]交错和 数位dp/记忆化搜索

    #1033 : 交错和 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描写叙述 给定一个数 x,设它十进制展从高位到低位上的数位依次是 a0, a1, ..., an - 1 ...

  6. hihoCoder 1033 : 交错和 数位dp

    思路:数位dp,dp(i, j, k)表示考虑i位数,每位数可以任意取[0~9],并且这i位数的交错和为j,k=1表示前缀全是0(如000456),k=0表示前缀不为0.注意,前缀是否为0是这道题的一 ...

  7. hihoCoder 1033: 交错和

    (1)题目描述: 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定一个数 x,设它十进制展从高位到低位上的数位依次是 a0, a1, ..., an - 1,定义交错 ...

  8. HihoCoder 1033交错和(数位DP第三题)

    (写挂了,有空再补) 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定一个数 x,设它十进制展从高位到低位上的数位依次是 a0, a1, ..., an - 1,定义 ...

  9. 【FJWC2017】交错和查询 [线段树]

    交错和查询 Time Limit: 10 Sec  Memory Limit: 256 MB Description 无限循环数字串S由长度为n的循环节s构成.设s为12345(n=5),则数字串S为 ...

随机推荐

  1. IIS 500.19 错误

    HTTP 错误 500.19 - Internal Server Error 错误代码 0x80070021 配置错误 不能在此路径中使用此配置节.如果在父级别上锁定了该节,便会出现这种情况.锁定是默 ...

  2. centos yum源配置

    5步搞定yum源配置 作者小波/QQ463431476欢迎转载! 第一步: 卸载原来的yum [root@localhost home]#rpm -qa|grep yum|xargs rpm -e - ...

  3. (二)cordova+framework7入门——笑笑APP

    [前言] framework7确实做的很赞,但是一直各种原因没有做什么app, 这个感觉就像大厨遇到百年难见的好材料,不炒个菜憋的慌, 机缘巧合周一周二两个晚上做了一个简单app,先看下效果: ios ...

  4. C++/C#互调步骤

    一.C#调用C++ dll步骤(只能导出方法):  * 1. c++建立空项目->源文件文件夹中添加cpp文件和函数  * 2. c++属性设置中,配置类型设置为动态库dll,公共语言运行时支持 ...

  5. 第8章 用户模式下的线程同步(3)_Slim读写锁(SRWLock)

    8.5 Slim读/写锁(SRWLock)——轻量级的读写锁 (1)SRWLock锁的目的 ①允许读者线程同一时刻访问共享资源(因为不存在破坏数据的风险) ②写者线程应独占资源的访问权,任何其他线程( ...

  6. java中使用二重循环打印图形

    如图所示:打印沙漏图形 1:因为外层循环控制图形行数,所以首先判断这四个选项能否循环五次 2:以上四个循环的表达式都能循环五次,我们从内层循环入手. A:int i=0;i<5;i++ 当i=1 ...

  7. NOIP模拟赛 最大匹配

    问题描述 mhy12345学习了二分图匹配,二分图是一种特殊的图,其中的点可以分到两个集合中,使得相同的集合中的点两两没有连边.     图的“匹配”是指这个图的一个边集,里面的边两两不存在公共端点. ...

  8. HTML 学习笔记 CSS3 (文本效果)

    text-shadow 语法 text-shadow : none | <length> none | [<shadow>, ] * <shadow> 或none ...

  9. 在实例中说明java的类变量,成员变量和局部变量

    java中一般有三种变量:类变量,成员变量和局部变量.类变量 1.下面先看类变量,看下面这个例子 public class Demo6{ public String name; public int ...

  10. iOS多线程开发

    概览 大家都知道,在开发过程中应该尽可能减少用户等待时间,让程序尽可能快的完成运算.可是无论是哪种语言开发的程序最终往往转换成汇编语言进而解释成机器码来执行.但是机器码是按顺序执行的,一个复杂的多步操 ...