题目描述

定义S(n)表示n的各个数位的k次方的和。定义$H(n)=min{n,S(n),H(S(n))}$。

求$$\sum _{i=A} ^{B} {H(i)} \mod 10000007$$

输入输出格式

输入格式:

一行三个数K、A、B。

【数据规模】

对于20%的数据,满足1≤A、B≤50;

对于100%的数据,满足1≤A、B≤10^6,K≤6.

输出格式:

B 一个数∑H(i) mod 10000007

i=A

输入输出样例

输入样例#1:

2 1 5
输出样例#1:

14

题解:

很暴力的解法,把每一个数都看作一个点,那么我们可以从一个数的每一位来得到它的下一个数,并向下一个数连一条有向边。

这样我们就得到了一个有向有环图,那么题意就变成了从一个点开始,一直向下走,所经过的所有点的最小值(包括环)。

考虑tarjan缩点,统计一下每一个强连通分量(也就是环)上的最小值。

很显然环上是没有出边的,我们将所有边反向,从入度为0的分量开始拓扑,一路上不断更新路径上的最小值,那么这样就统计出来了每一个点一直向下走,所经过的所有点的最小值。

然后把题目要求的点加在一起输出就可以了。(我用的是前缀和)

另外不要怀疑这道题会因为点过多而超时,当k=6时,以1~100000分别为起点,所经过的数的最大值是3188...(反正是个七位数),还是可以承受的。

时空复杂度O(能过)

 //Never forget why you start
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
#define mod (10000007)
using namespace std;
int n,t[];
bool vis[];
int suan(int x){
int ans=;
while(x){
ans+=t[x%];
x/=;
}
return ans;
}
int to[];
void dfs(int r){
if(vis[r])return;
vis[r]=;
int Next=suan(r);
to[r]=Next;
dfs(Next);
}
int dfn[],low[],sccno[],scc,dfscnt,mmin[];
int s[],top;
void tarjan(int r){
dfn[r]=low[r]=++dfscnt;
s[++top]=r;
int y=to[r];
if(!dfn[y]){
tarjan(y);
low[r]=min(low[r],low[y]);
}
else if(!sccno[y])low[r]=min(low[r],dfn[y]);
if(low[r]==dfn[r]){
scc++;
int x;
while(){
x=s[top--];
sccno[x]=scc;
mmin[scc]=min(x,mmin[scc]);
if(x==r)break;
}
}
}
struct node{
int next,to;
}edge[];
int size=;
void putin(int from,int to){
size++;
edge[size].to=to;
edge[size].next=dfn[from];
dfn[from]=size;
}
void bfs(){
queue<int>mem;
for(int i=;i<=scc;i++)if(!s[i])mem.push(i);
while(!mem.empty()){
int x=mem.front();mem.pop();
for(int i=dfn[x];i!=-;i=edge[i].next){
int y=edge[i].to;
mmin[y]=min(mmin[y],mmin[x]);
s[y]--;
if(!s[y])mem.push(y);
}
}
}
int main(){
int i,j;
scanf("%d",&n);
memset(mmin,/,sizeof(mmin));
for(i=;i<=;i++)t[i]=pow(i,n);
for(i=;i<=;i++){
dfs(i);
}
for(i=;i<=;i++)
if(!dfn[i])tarjan(i);
memset(dfn,-,sizeof(dfn));
memset(s,,sizeof(s));
for(i=;i<=;i++)
if(sccno[i]!=sccno[to[i]])putin(sccno[to[i]],sccno[i]),s[sccno[i]]++;
bfs();
low[]=;
for(i=;i<=;i++){
low[i]=mmin[sccno[i]];
(low[i]+=low[i-])%=mod;
}
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",(low[r]-low[l-]+mod)%mod);
return ;
}

[luogu 1660]数位平方和的更多相关文章

  1. 数位dp & 热身训练7

    数位dp 数位dp是一种计数用的dp,一般就是要统计一段区间$[L,R]$内,满足一定条件的数的个数,或者各个数位的个数. 数位dp使得暴力枚举变为满足一定状态的记忆化,更加优秀. 数位dp常常会考虑 ...

  2. Happy Number - LeetCode

    examination questions Write an algorithm to determine if a number is "happy". A happy numb ...

  3. Project Euler 92:Square digit chains C++

    A number chain is created by continuously adding the square of the digits in a number to form a new ...

  4. [luogu3413]萌数

    [luogu3413]萌数 luogu 考虑数位dp 怎么判断一个数是不是萌数? 只要知道其中某一位和它的前一位相等或者和前一位的前一位相等,那么它就是一个萌数 什么样的数不是萌数? 对于它的每一位都 ...

  5. Java判断一个数是不是快乐数

    快乐数的定义: 快乐数(happy number)有以下的特性: 在给定的进位制下,该数字所有数位(digits)的平方和,得到的新数再次求所有数位的平方和,如此重复进行,最终结果必为1. 以十进制为 ...

  6. LeetCode(202) Happy Number

    题目 Write an algorithm to determine if a number is "happy". A happy number is a number defi ...

  7. LeetCode 202: 快乐数 Happy Number

    题目: 编写一个算法来判断一个数是不是 "快乐数". 一个 "快乐数" 定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直 ...

  8. 清明 DAY 3

    ans=1000*4 分别固定千位,百位,十位,个位为1,其余位置随便排 对于每一个质因数的n次方,共有n+1中选择方法,即这个质因数的0~n次方 故共有   4*3*5=60  种方法 (1)取两册 ...

  9. 2021record

    2021-10-14 P2577 [ZJOI2004]午餐 2021-10-13 CF815C Karen and Supermarket(小小紫题,可笑可笑) P6748 『MdOI R3』Fall ...

随机推荐

  1. net start sql server (instance)

    如何启动 SQL Server 实例(net 命令) 其他版本   可以使用 Microsoft Windows net 命令启动 Microsoft SQL Server 服务. 启动 SQL Se ...

  2. C++类和对象的一个简单的实例

    题目:找出一个整形数组中的元素的最大值 下面,我们用类和对象的方法来做. #include<iostream> using namespace std; class Array_max{ ...

  3. cocos2dx之tolua++全面分析(一):tolua++工具本身

    在cocos2dx/tools/tolua++下面,有大量pkg文件,这些是按tolua++要求格式写好的.需要导出到lua中的c++类描述文件. 每当在c++类里增加了新函数需要导出时,应同步修改相 ...

  4. C#中IQueryable和IEnumerable的区别

    最近的一个面试中,被问到IQueryable 和 IEnumerable的区别, 我自己看了一些文章,总结如下: 1. 要明白一点,IQueryable接口是继承自IEnumerable的接口的. 2 ...

  5. 【转】eclipse中window->preference选项中没有tomcat的解决方法

    eclipse中window->preference选项中没有tomcat的解决方法 2011-09-09 13:46:35|  分类: eclipse|字号 订阅 其实一共有好几种方法,这只是 ...

  6. Free Style Structure text

    最近用了很多文本配置输入,考虑一个最简单的格式,适合C语言scanf读写数据. 基本数据类型直接使用常用形式. double 直接用小数,对应%f读取. int 直接用十进制整数,对应%d读取. ch ...

  7. Android常见内存泄露,学会这六招优化APP性能

    很多开发者都知道,在面试的时候会经常被问到内存泄露和内存溢出的问题. 1.内存溢出(Out Of Memory,简称 OOM),通俗理解就是内存不够,即内存占用超出内存的空间大小. 2.内存泄漏(Me ...

  8. 2017-10-1 清北刷题冲刺班a.m

    位运算1 (bit) Time Limit:1000ms   Memory Limit:128MB 题目描述 LYK拥有一个十进制的数N.它赋予了N一个新的意义:将N每一位都拆开来后再加起来就是N所拥 ...

  9. Hadoop集群配置免密SSH登录方法

    Hadoop集群包含1个主节点和3个从节点,需要实现各节点之间的免密码登录,下面介绍具体的实现方法. 一.Hadoop集群环境 二.免密登录原理 每台主机authorized_keys文件里面包含的主 ...

  10. Scanner类、Random类、ArrayList类

    先写个框架,复习内容后来添加... 先写个框架,复习内容后来添加... 先写个框架,复习内容后来添加... 先写个框架,复习内容后来添加... 先写个框架,复习内容后来添加... 先写个框架,复习内容 ...