【JZOJ 4912】幻想

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(T2(RL))
(可能需要卡常)

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值