Description
Solution
来考虑一下把每个位置的值都求出来,
想一下位置x的数可以转移到哪里去,当k=2时:
1. 在原地不动;
2. 转移到
x+2k
这个位置,并值+1;
咦,这个怎么这么像二进制,位置i的数值不就是i在二进制下1的个数mod 2吗,
发现这个性质在k为其他值使依旧适用,
所以,题目就变成了求L~R之间的每个数在k进制下位数之和mod k的值加上哈希的值,
又因为一个高精度的数连续加n次1,进位次数不超过2n次,(证明看这里)
所以总复杂度:
O(T∗2(R−L))
(可能需要卡常)
Code
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#define fo(i,a,b) for(LL i=a;i<=b;i++)
#define sqr(q) ((q)*(q))
#define H(q) ((sqr((LL)q%chens)+q+(LL)804)/(chushu))
using namespace std;
typedef long long LL;
const int N=150;
const LL mo=4294967296,chens=20000116,chushu=233;
LL read(LL &n)
{
char ch=getchar();
while((ch!='-')&&((ch<'0')||(ch>'9')))ch=getchar();
LL q=0,w=1;if(ch=='-') w=-1;else q=q*10+(LL)(ch)-48;ch=getchar();
while(ch>='0' && ch<='9')q=q*10+(LL)(ch)-48,ch=getchar();n=q*w;return(n);
}
LL m,l,r,ans;
LL a[N];
int main()
{
freopen("fantasy.in","r",stdin);
freopen("fantasy.out","w",stdout);
LL q,w;
int _=read(q);
while(_--)
{
read(m),read(l),read(r);
if(l<1)l=1;
r-=l;q=l;w=0;
memset(a,0,sizeof(a));
for(;q;q/=m)w+=a[++a[0]]=q%m;
ans=0;w%=m;
fo(i,0,r)
{
ans=(ans+((sqr((LL)(i+l)%chens)+i+l+(LL)804)/(chushu))*w%mo)%mo;
a[1]++;w++;
for(int j=1;j<=a[0]&&a[j]>=m;j++)a[j]-=m,a[j+1]++,w++;
if(a[a[0]+1])a[0]++;
while(w>=m)w-=m;
}
printf("%lld\n",ans);
}
return 0;
}