悲剧的数论题

原题,结果还是没做出来

题意:定义n为正整数,S(n)为 n的各位数字之和,令d[n]:={s[n] n<10,d[s[n]] n>=10} 求给定l到r中有多少n满足n=x*d[x],x任意。

不难求出d[n]:=(n-1) mod 9+1,通过这个式子:

(x-1) mod 9=d[x]-1

x-1=9*t+d[x]-1

x=9*t+d[x]

n=x*d[x]=(9*t+d[x])*d[x]=9*d[x]*t+d[x]^2

d[x]只有9种取值,即可得出9个式子。

列出d[x]^2 mod 9 的表,1,4,0,7,7,0,4,1,0

其中式子1与式子8余数相同,进行讨论,9*t+1与72*t+64,  9*(8*t+7)+1=72*t+64,所以式子8可用式子1得出,为包含关系。

同理式子6可用式子3得出

讨论式子4与式子5,无法完全表示

36*t+16;45*t+25;

同除以9:x/9=4*t+16/9;y/9=5*t+25/9——>(x-7)/9=4*t+1;(y-7)/9=5*t+2;我们发现式子左边相同,这两个式子有交集,4,5互素,运用中国同余定理。

在[1,20]中仅一个值满足两式,通过枚举得17,则17+20亦为解、、、,得出新式20*s+17=(x-7)/9,整理得x=180*s+160。

运用容斥原理,求式子4、5并集,减去上式。

同理讨论式子2、7.

对于式子3、9,mod 9余数相同,mod 27 余数不同,所以实际上是没有交集的。

列不等式<=r的解集-<=l-1的解集即为答案

var ans1,ans2,l,r:int64;
    t:longint;
procedure count(var ans:int64;x,y,z:int64);
begin
 ans:=ans+(z-y+x) div x
end;
procedure count2(var ans:int64;x,y,z:int64);
begin
 ans:=ans-(z-y+x) div x
end;
procedure init;
begin
 readln(l,r);
 ans1:=0;
 count(ans1,9,1,l-1);count(ans1,18,4,l-1);count(ans1,27,9,l-1);count(ans1,36,16,l-1);
 count(ans1,45,25,l-1);count(ans1,63,49,l-1);count(ans1,81,81,l-1);
 count2(ans1,9*14,8*14,l-1);count2(ans1,9*20,8*20,l-1);
 ans2:=0;
 count(ans2,9,1,r);count(ans2,18,4,r);count(ans2,27,9,r);count(ans2,36,16,r);
 count(ans2,45,25,r);count(ans2,63,49,r);count(ans2,81,81,r);
 count2(ans2,9*14,8*14,r);count2(ans2,9*20,8*20,r);
 writeln(ans2-ans1)
end;
begin
assign(input,'num.in');reset(input);
assign(output,'num.out');rewrite(output);
 readln(t);
 for t:=1 to t do init;
close(input);close(output)
end.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值